清理已迁移的 cart 代码

This commit is contained in:
YunaiV
2022-09-12 10:00:17 +08:00
parent a347d2a1d3
commit 239c38cf64
113 changed files with 0 additions and 5310 deletions

View File

@@ -1,36 +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>trade-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>trade-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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</project>

View File

@@ -39,11 +39,6 @@ public interface OrderErrorCodeConstants {
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, "订单物流调用失败!");

View File

@@ -1,61 +0,0 @@
package cn.iocoder.mall.tradeservice.rpc.cart;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* Title:
* Description:
*
* @author zhuyang
* @version 1.0 2021/10/9
*/
@FeignClient(value = "trade-service")
public interface CartFeign {
/**
* 添加商品到购物车
*
* @param addReqDTO 添加商品信息
* @return 成功
*/
@PostMapping("/trade/cart/addCartItem")
CommonResult<Boolean> addCartItem(@RequestBody CartItemAddReqDTO addReqDTO);
/**
* 更新购物车商品数量
*
* @param updateQuantityReqDTO 更新商品数量 DTO
* @return 成功
*/
@PostMapping("/trade/cart/updateCartItemQuantity")
CommonResult<Boolean> updateCartItemQuantity(@RequestBody CartItemUpdateQuantityReqDTO updateQuantityReqDTO);
/**
* 更新购物车商品是否选中
*
* @param updateSelectedReqDTO 更新商品是否选中 DTO
* @return 成功
*/
@PostMapping("/trade/cart/updateCartItemSelected")
CommonResult<Boolean> updateCartItemSelected(@RequestBody CartItemUpdateSelectedReqDTO updateSelectedReqDTO);
/**
* 删除购物车商品列表
*
* @param deleteListReqDTO 删除商品列表 DTO
* @return 成功
*/
@PostMapping("/trade/cart/deleteCartItems")
CommonResult<Boolean> deleteCartItems(@RequestBody CartItemDeleteListReqDTO deleteListReqDTO);
@GetMapping("/sumCartItemQuantity")
public CommonResult<Integer> sumCartItemQuantity(@RequestParam("userId") Integer userId) ;
@PostMapping("/trade/cart/listCartItems")
public CommonResult<List<CartItemRespDTO>> listCartItems(@RequestBody CartItemListReqDTO listReqDTO) ;
}

View File

@@ -1,34 +0,0 @@
package cn.iocoder.mall.tradeservice.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;
}

View File

@@ -1,28 +0,0 @@
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 购物车删除商品列表 Request DTO
*/
@Data
@Accessors(chain = true)
public class CartItemDeleteListReqDTO implements Serializable {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Integer userId;
/**
* 商品 SKU 编号列表
*/
@NotNull(message = "商品 SKU 编号列表不能为空")
private List<Integer> skuIds;
}

View File

@@ -1,26 +0,0 @@
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 购物车的商品信息查询 BO
*/
@Data
@Accessors(chain = true)
public class CartItemListReqDTO implements Serializable {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Integer userId;
/**
* 是否选中
*/
private Boolean selected;
}

View File

@@ -1,67 +0,0 @@
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 购物车的商品信息 Response DTO
*/
@Data
@Accessors(chain = true)
public class CartItemRespDTO implements Serializable {
// ========= 基础字段 BEGIN =========
/**
* 编号,唯一自增。
*/
private Integer id;
/**
* 是否选中
*/
private Boolean selected;
// ========= 基础字段 END =========
// ========= 买家信息 BEGIN =========
/**
* 用户编号
*/
private Integer userId;
// ========= 买家信息 END =========
// ========= 商品信息 BEGIN =========
/**
* 商品 SPU 编号
*/
private Integer spuId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品购买数量
*/
private Integer quantity;
// ========= 商品信息 END =========
// ========= 优惠信息 BEGIN =========
// /**
// * 商品营销活动编号
// */
// private Integer activityId;
// /**
// * 商品营销活动类型
// */
// private Integer activityType;
// ========= 优惠信息 END =========
}

View File

@@ -1,34 +0,0 @@
package cn.iocoder.mall.tradeservice.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;
}

View File

@@ -1,33 +0,0 @@
package cn.iocoder.mall.tradeservice.rpc.cart.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Collection;
/**
* 购物车更新是否选中 Request DTO
*/
@Data
@Accessors(chain = true)
public class CartItemUpdateSelectedReqDTO implements Serializable {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Integer userId;
/**
* 商品 SKU 编号列表
*/
@NotNull(message = "商品 SKU 编号列表不能为空")
private Collection<Integer> skuIds;
/**
* 是否选中
*/
@NotNull(message = "是否选中不能为空")
private Boolean selected;
}

View File

@@ -1,147 +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>trade-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>trade-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>trade-service-api</artifactId>
</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>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</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>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</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>
<!-- Test 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>

View File

@@ -1,17 +0,0 @@
package cn.iocoder.mall.tradeservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"cn.iocoder.mall.productservice.rpc","cn.iocoder.mall.promotion.api.rpc","cn.iocoder.mall.userservice.rpc"})
public class TradeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(TradeServiceApplication.class, args);
}
}

View File

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

View File

@@ -1,12 +0,0 @@
package cn.iocoder.mall.tradeservice.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Spring Aop 配置类
*/
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class AopConfiguration {
}

View File

@@ -1,28 +0,0 @@
package cn.iocoder.mall.tradeservice.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.tradeservice.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 分页插件
}
}

View File

@@ -1,74 +0,0 @@
package cn.iocoder.mall.tradeservice.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
import cn.iocoder.mall.tradeservice.service.cart.CartManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@RestController
@RequestMapping("/trade/cart")
public class CartController {
@Autowired
private CartManager cartManager;
/**
* 添加商品到购物车
*
* @param addReqDTO 添加商品信息
* @return 成功
*/
@PostMapping("addCartItem")
CommonResult<Boolean> addCartItem(@RequestBody CartItemAddReqDTO addReqDTO){
cartManager.addCartItem(addReqDTO);
return success(true);
}
/**
* 更新购物车商品数量
*
* @param updateQuantityReqDTO 更新商品数量 DTO
* @return 成功
*/
@PostMapping("updateCartItemQuantity")
CommonResult<Boolean> updateCartItemQuantity(@RequestBody CartItemUpdateQuantityReqDTO updateQuantityReqDTO){
cartManager.updateCartItemSelected(updateQuantityReqDTO);
return success(true);
}
/**
* 更新购物车商品是否选中
*
* @param updateSelectedReqDTO 更新商品是否选中 DTO
* @return 成功
*/
@PostMapping("updateCartItemSelected")
CommonResult<Boolean> updateCartItemSelected(@RequestBody CartItemUpdateSelectedReqDTO updateSelectedReqDTO){
cartManager.updateCartItemSelected(updateSelectedReqDTO);
return success(true);
}
/**
* 删除购物车商品列表
*
* @param deleteListReqDTO 删除商品列表 DTO
* @return 成功
*/
@PostMapping("deleteCartItems")
CommonResult<Boolean> deleteCartItems(@RequestBody CartItemDeleteListReqDTO deleteListReqDTO){
cartManager.deleteCartItems(deleteListReqDTO);
return success(true);
}
@GetMapping("/sumCartItemQuantity")
public CommonResult<Integer> sumCartItemQuantity(@RequestParam("userId") Integer userId) {
return success(cartManager.sumCartItemQuantity(userId));
}
@PostMapping("/listCartItems")
public CommonResult<List<CartItemRespDTO>> listCartItems(@RequestBody CartItemListReqDTO listReqDTO) {
return success(cartManager.listCartItems(listReqDTO));
}
}

View File

@@ -1,30 +0,0 @@
package cn.iocoder.mall.tradeservice.convert.cart;
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;
import java.util.List;
@Mapper
public interface CartConvert {
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
CartItemDO convert(CartItemAddBO bean);
CartItemAddBO convert(CartItemAddReqDTO bean);
List<CartItemBO> convertList(List<CartItemDO> list);
CartItemListQueryBO convert(CartItemListReqDTO bean);
List<CartItemRespDTO> convertList02(List<CartItemBO> list);
}

View File

@@ -1,29 +0,0 @@
package cn.iocoder.mall.tradeservice.convert.order;
import cn.iocoder.common.framework.vo.PageResult;
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.rpc.order.dto.TradeOrderItemRespDTO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface TradeOrderConvert {
TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);
TradeOrderRespDTO convert(TradeOrderDO bean);
@Mapping(source = "records", target = "list")
PageResult<TradeOrderRespDTO> convertPage(IPage<TradeOrderDO> page);
List<TradeOrderItemRespDTO> convertList(List<TradeOrderItemDO> list);
TradeOrderItemRespDTO convert(TradeOrderItemDO bean);
}

View File

@@ -1,73 +0,0 @@
package cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 购物车的商品信息 DO
*/
@TableName("cart_item")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class CartItemDO extends DeletableDO {
// ========= 基础字段 BEGIN =========
/**
* 编号,唯一自增。
*/
private Integer id;
/**
* 是否选中
*/
private Boolean selected;
// ========= 基础字段 END =========
// ========= 买家信息 BEGIN =========
/**
* 用户编号
*/
private Integer userId;
// ========= 买家信息 END =========
// ========= 商品信息 BEGIN =========
/**
* 商品 SPU 编号
*/
private Integer spuId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品购买数量
*/
private Integer quantity;
// TODO 冗余字段
// ========= 商品信息 END =========
// ========= 优惠信息 BEGIN =========
// /**
// * 商品营销活动编号
// */
// private Integer activityId;
// /**
// * 商品营销活动类型
// */
// private Integer activityType;
// ========= 优惠信息 END =========
}

View File

@@ -1,49 +0,0 @@
package cn.iocoder.mall.tradeservice.dal.mysql.mapper.cart;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemListQueryBO;
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.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
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)));
}
default Integer selectSumQuantityByUserId(Integer userId) {
// SQL sum 查询
List<Map<String, Object>> result = selectMaps(new QueryWrapper<CartItemDO>()
.select("SUM(quantity) AS sumQuantity")
.eq("user_id", userId));
// 获得数量
return ((BigDecimal) result.get(0).get("sumQuantity")).intValue();
}
default List<CartItemDO> selectList(CartItemListQueryBO queryBO) {
return selectList(new QueryWrapperX<CartItemDO>().eq("user_id", queryBO.getUserId())
.eqIfPresent("selected", queryBO.getSelected()));
}
}

View File

@@ -1,114 +0,0 @@
package cn.iocoder.mall.tradeservice.service.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.productservice.rpc.sku.ProductSkuFeign;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
import cn.iocoder.mall.tradeservice.convert.cart.CartConvert;
import cn.iocoder.mall.tradeservice.rpc.cart.dto.*;
import cn.iocoder.mall.tradeservice.service.cart.bo.CartItemBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.CARD_ITEM_SKU_NOT_FOUND;
/**
* 购物车 Manager
*/
@Service
public class CartManager {
@Autowired
private ProductSkuFeign productSkuFeign;
@Autowired
private CartService cartService;
/**
* 添加商品到购物车
*
* @param addReqDTO 添加商品信息
*/
public void addCartItem(CartItemAddReqDTO addReqDTO) {
// 校验商品 SKU 是否合法
ProductSkuRespDTO skuDTO = this.checkProductSku(addReqDTO.getSkuId());
// 添加购物车项
cartService.addCartItem(CartConvert.INSTANCE.convert(addReqDTO).setSpuId(skuDTO.getSpuId()), 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());
}
/**
* 更新购物车商品是否选中
*
* @param updateSelectedReqDTO 更新商品是否选中 DTO
*/
public void updateCartItemSelected(CartItemUpdateSelectedReqDTO updateSelectedReqDTO) {
cartService.updateCartItemSelected(updateSelectedReqDTO.getUserId(),
updateSelectedReqDTO.getSkuIds(), updateSelectedReqDTO.getSelected());
}
/**
* 删除购物车商品列表
*
* @param deleteListReqDTO 删除商品列表 DTO
*/
public void deleteCartItems(CartItemDeleteListReqDTO deleteListReqDTO) {
cartService.deleteCartItems(deleteListReqDTO.getUserId(),
deleteListReqDTO.getSkuIds());
}
/**
* 查询用户在购物车中的商品数量
*
* @param userId 用户编号
* @return 商品数量
*/
public Integer sumCartItemQuantity(Integer userId) {
return cartService.sumCartItemQuantity(userId);
}
/**
* 查询用户在购物车种的商品列表
*
* @param listReqDTO 查询条件 DTO
* @return 购物车中商品列表信息
*/
public List<CartItemRespDTO> listCartItems(CartItemListReqDTO listReqDTO) {
List<CartItemBO> cartItemBOs = cartService.listCartItems(CartConvert.INSTANCE.convert(listReqDTO));
return CartConvert.INSTANCE.convertList02(cartItemBOs);
}
/**
* 校验商品 SKU 是否合法
* 1. 是否存在
* 2. 是否下架
*
* @param skuId 商品 SKU 编号
* @return 商品 SKU 信息
*/
private ProductSkuRespDTO checkProductSku(Integer skuId) {
CommonResult<ProductSkuRespDTO> getProductSkuResult = productSkuFeign.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;
}
}

View File

@@ -1,136 +0,0 @@
package cn.iocoder.mall.tradeservice.service.cart;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.mall.tradeservice.convert.cart.CartConvert;
import cn.iocoder.mall.tradeservice.dal.mysql.dataobject.cart.CartItemDO;
import cn.iocoder.mall.tradeservice.dal.mysql.mapper.cart.CartItemMapper;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.CARD_ITEM_NOT_FOUND;
import static cn.iocoder.mall.tradeservice.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, Collection<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 deleteCartItems(Integer userId, List<Integer> skuIds) {
// 查询 CartItemDO 列表
List<CartItemDO> itemDOs = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
if (CollectionUtils.isEmpty(itemDOs)) {
return;
}
// 批量标记删除
cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(itemDOs, CartItemDO::getId));
}
/**
* 查询用户在购物车中的商品数量
*
* @param userId 用户编号
* @return 商品数量
*/
public Integer sumCartItemQuantity(Integer userId) {
return cartItemMapper.selectSumQuantityByUserId(userId);
}
/**
* 查询用户在购物车种的商品列表
*
* @param queryBO 查询条件 BO
* @return 购物车中商品列表信息
*/
public List<CartItemBO> listCartItems(CartItemListQueryBO queryBO) {
List<CartItemDO> cartItemDOs = cartItemMapper.selectList(queryBO);
return CartConvert.INSTANCE.convertList(cartItemDOs);
}
}

View File

@@ -1,38 +0,0 @@
package cn.iocoder.mall.tradeservice.service.cart.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* 购物车添加购物项 Request DTO
*/
@Data
@Accessors(chain = true)
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;
}

View File

@@ -1,65 +0,0 @@
package cn.iocoder.mall.tradeservice.service.cart.bo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 购物车的商品信息 BO
*/
@Data
@Accessors(chain = true)
public class CartItemBO {
// ========= 基础字段 BEGIN =========
/**
* 编号,唯一自增。
*/
private Integer id;
/**
* 是否选中
*/
private Boolean selected;
// ========= 基础字段 END =========
// ========= 买家信息 BEGIN =========
/**
* 用户编号
*/
private Integer userId;
// ========= 买家信息 END =========
// ========= 商品信息 BEGIN =========
/**
* 商品 SPU 编号
*/
private Integer spuId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品购买数量
*/
private Integer quantity;
// ========= 商品信息 END =========
// ========= 优惠信息 BEGIN =========
// /**
// * 商品营销活动编号
// */
// private Integer activityId;
// /**
// * 商品营销活动类型
// */
// private Integer activityType;
// ========= 优惠信息 END =========
}

View File

@@ -1,25 +0,0 @@
package cn.iocoder.mall.tradeservice.service.cart.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 购物车的商品信息查询 BO
*/
@Data
@Accessors(chain = true)
public class CartItemListQueryBO {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Integer userId;
/**
* 是否选中
*/
private Boolean selected;
}

View File

@@ -1,48 +0,0 @@
package cn.iocoder.mall.tradeservice.service.order;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderPageReqDTO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
import java.util.Collection;
/**
* 交易订单 Service 接口
*/
public interface TradeOrderService {
/**
* 创建交易订单
*
* @param createReqDTO 订单信息
* @return 订单编号
*/
Integer createTradeOrder(TradeOrderCreateReqDTO createReqDTO);
/**
* 获得订单交易
*
* @param tradeOrderId 订单交易编号
* @param fields 额外返回字段,可见 {@link cn.iocoder.mall.tradeservice.enums.order.TradeOrderDetailFieldEnum}
* @return 订单交易
*/
TradeOrderRespDTO getTradeOrder(Integer tradeOrderId, Collection<String> fields);
/**
* 获得订单交易分页
*
* @param pageReqDTO 订单交易分页查询
* @return 订单交易分页结果
*/
PageResult<TradeOrderRespDTO> pageTradeOrder(TradeOrderPageReqDTO pageReqDTO);
/**
* 更新交易订单支付成功
*
* @param tradeOrderId 交易订单编号
* @param payAmount 支付金额
*/
void updateTradeOrderPaySuccess(Integer tradeOrderId, Integer payAmount);
}

View File

@@ -1,279 +0,0 @@
package cn.iocoder.mall.tradeservice.service.order.impl;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.common.framework.util.MathUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.payservice.rpc.transaction.dto.PayTransactionCreateReqDTO;
import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO;
import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO;
import cn.iocoder.mall.tradeservice.client.pay.PayTransactionClient;
import cn.iocoder.mall.tradeservice.client.product.ProductSkuClient;
import cn.iocoder.mall.tradeservice.client.promotion.CouponCardClient;
import cn.iocoder.mall.tradeservice.client.promotion.PriceClient;
import cn.iocoder.mall.tradeservice.client.user.UserAddressClient;
import cn.iocoder.mall.tradeservice.config.TradeBizProperties;
import cn.iocoder.mall.tradeservice.convert.order.TradeOrderConvert;
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.dal.mysql.mapper.order.TradeOrderItemMapper;
import cn.iocoder.mall.tradeservice.dal.mysql.mapper.order.TradeOrderMapper;
import cn.iocoder.mall.tradeservice.enums.logistics.LogisticsDeliveryTypeEnum;
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderAfterSaleStatusEnum;
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderDetailFieldEnum;
import cn.iocoder.mall.tradeservice.enums.order.TradeOrderStatusEnum;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderCreateReqDTO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderPageReqDTO;
import cn.iocoder.mall.tradeservice.rpc.order.dto.TradeOrderRespDTO;
import cn.iocoder.mall.tradeservice.service.order.TradeOrderService;
import cn.iocoder.mall.userservice.rpc.address.dto.UserAddressRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.common.framework.util.CollectionUtils.convertSet;
import static cn.iocoder.mall.tradeservice.enums.OrderErrorCodeConstants.*;
import static cn.iocoder.mall.userservice.enums.UserErrorCodeConstants.USER_ADDRESS_NOT_FOUND;
/**
* 交易订单 Service 实现
*/
@Service
public class TradeOrderServiceImpl implements TradeOrderService {
@Autowired
private TradeOrderMapper tradeOrderMapper;
@Autowired
private TradeOrderItemMapper tradeOrderItemMapper;
@Autowired // 注入自己,用于调用事务方法
private TradeOrderServiceImpl self;
@Autowired
private UserAddressClient userAddressClient;
@Autowired
private ProductSkuClient productSkuClient;
@Autowired
private PriceClient priceClient;
@Autowired
private CouponCardClient couponCardClient;
@Autowired
private PayTransactionClient payTransactionClient;
@Autowired
private TradeBizProperties tradeBizProperties;
@Override
// @GlobalTransactional TODO 芋艿,使用 seata 实现分布式事务
public Integer createTradeOrder(TradeOrderCreateReqDTO createReqDTO) {
// 获得收件地址
UserAddressRespDTO userAddressRespDTO = userAddressClient.getUserAddress(createReqDTO.getUserAddressId(),
createReqDTO.getUserId());
if (userAddressRespDTO == null) {
throw ServiceExceptionUtil.exception(USER_ADDRESS_NOT_FOUND);
}
// 获得商品信息
List<ProductSkuRespDTO> listProductSkus = productSkuClient.listProductSkus(
convertSet(createReqDTO.getOrderItems(), TradeOrderCreateReqDTO.OrderItem::getSkuId),
ProductSkuDetailFieldEnum.SPU.getField());
if (listProductSkus.size() != createReqDTO.getOrderItems().size()) { // 校验获得的数量,是否匹配
throw ServiceExceptionUtil.exception(ORDER_GET_GOODS_INFO_INCORRECT);
}
// 价格计算
PriceProductCalcRespDTO priceProductCalcRespDTO = priceClient.calcProductPrice(createReqDTO.getUserId(),
createReqDTO.getOrderItems().stream().map(orderItem -> new PriceProductCalcReqDTO.Item().setSkuId(orderItem.getSkuId())
.setQuantity(orderItem.getQuantity()).setSelected(true)).collect(Collectors.toList()),
createReqDTO.getCouponCardId());
// TODO 芋艿,扣除库存
// 标记优惠劵已使用
if (createReqDTO.getCouponCardId() != null) {
couponCardClient.useCouponCard(createReqDTO.getUserId(), createReqDTO.getCouponCardId());
}
// 创建交易订单(本地事务)
TradeOrderDO tradeOrderDO = self.createTradeOrder0(createReqDTO, listProductSkus, priceProductCalcRespDTO, userAddressRespDTO);
// 创建支付订单,对接支付服务
createPayTransaction(tradeOrderDO, createReqDTO, listProductSkus);
return tradeOrderDO.getId();
}
@Transactional
public TradeOrderDO createTradeOrder0(TradeOrderCreateReqDTO createReqDTO, List<ProductSkuRespDTO> listProductSkus,
PriceProductCalcRespDTO priceProductCalcRespDTO, UserAddressRespDTO userAddressRespDTO) {
// 构建 TradeOrderDO 对象,并进行保存
TradeOrderDO tradeOrderDO = new TradeOrderDO();
// 1. 基本信息
tradeOrderDO.setUserId(createReqDTO.getUserId()).setOrderNo(generateTradeOrderNo())
.setOrderStatus(TradeOrderStatusEnum.WAITING_PAYMENT.getValue()).setRemark(createReqDTO.getRemark());
// 2. 价格 + 支付基本信息
tradeOrderDO.setBuyPrice(priceProductCalcRespDTO.getFee().getBuyTotal())
.setDiscountPrice(priceProductCalcRespDTO.getFee().getDiscountTotal())
.setLogisticsPrice(priceProductCalcRespDTO.getFee().getPostageTotal())
.setPresentPrice(priceProductCalcRespDTO.getFee().getPresentTotal())
.setPayPrice(0).setRefundPrice(0);
// 3. 收件 + 物流基本信息
tradeOrderDO.setDeliveryType(LogisticsDeliveryTypeEnum.EXPRESS.getDeliveryType())
.setReceiverName(userAddressRespDTO.getName()).setReceiverMobile(userAddressRespDTO.getMobile())
.setReceiverAreaCode(userAddressRespDTO.getAreaCode()).setReceiverDetailAddress(userAddressRespDTO.getDetailAddress());
// 4. 售后基本信息
tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NULL.getStatus());
// 5. 营销基本信息
tradeOrderDO.setCouponCardId(createReqDTO.getCouponCardId());
// 最终保存
tradeOrderMapper.insert(tradeOrderDO);
// 创建 TradeOrderItemDO 数组,并进行保存
List<TradeOrderItemDO> tradeOrderItemDOs = new ArrayList<>(listProductSkus.size());
Map<Integer, ProductSkuRespDTO> listProductSkuMap = CollectionUtils.convertMap(listProductSkus, ProductSkuRespDTO::getId);
Map<Integer, PriceProductCalcRespDTO.Item> priceItemMap = new HashMap<>(); // 商品 SKU 价格的映射
priceProductCalcRespDTO.getItemGroups().forEach(itemGroup ->
itemGroup.getItems().forEach(item -> priceItemMap.put(item.getSkuId(), item)));
for (TradeOrderCreateReqDTO.OrderItem orderItem : createReqDTO.getOrderItems()) {
TradeOrderItemDO tradeOrderItemDO = new TradeOrderItemDO();
tradeOrderItemDOs.add(tradeOrderItemDO);
// 1. 基本信息
tradeOrderItemDO.setOrderId(tradeOrderDO.getId()).setStatus(tradeOrderDO.getOrderStatus());
// 2. 商品基本信息
ProductSkuRespDTO productSkuRespDTO = listProductSkuMap.get(orderItem.getSkuId());
tradeOrderItemDO.setSpuId(productSkuRespDTO.getSpuId()).setSkuId(productSkuRespDTO.getId())
.setSkuName(productSkuRespDTO.getSpu().getName())
.setSkuImage(CollectionUtils.getFirst(productSkuRespDTO.getSpu().getPicUrls()))
.setQuantity(orderItem.getQuantity());
// 3. 价格 + 支付基本信息
PriceProductCalcRespDTO.Item priceItem = priceItemMap.get(orderItem.getSkuId());
tradeOrderItemDO.setOriginPrice(priceItem.getOriginPrice()).setBuyPrice(priceItem.getBuyPrice())
.setPresentPrice(priceItem.getPresentPrice()).setBuyTotal(priceItem.getBuyTotal())
.setDiscountTotal(priceItem.getDiscountTotal()).setPresentTotal(priceItem.getPresentTotal())
.setRefundTotal(0);
// 4. 物流基本信息
// 5. 售后基本信息
tradeOrderItemDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NULL.getStatus());
}
// 最终保存
tradeOrderItemMapper.insertList(tradeOrderItemDOs);
return tradeOrderDO;
}
private void createPayTransaction(TradeOrderDO tradeOrderDO, TradeOrderCreateReqDTO createReqDTO,
List<ProductSkuRespDTO> listProductSkus) {
// 创建支付单
String orderSubject = listProductSkus.get(0).getSpu().getName();
Date expireTime = DateUtil.addDate(Calendar.MINUTE, tradeBizProperties.getPayExpireTime());
Integer payTransactionId = payTransactionClient.createPayTransaction(
new PayTransactionCreateReqDTO().setUserId(createReqDTO.getUserId())
.setCreateIp(createReqDTO.getIp()).setAppId(tradeBizProperties.getPayAppId())
.setOrderId(tradeOrderDO.getId().toString()).setExpireTime(expireTime)
.setPrice(tradeOrderDO.getPresentPrice()).setOrderSubject(orderSubject)
.setOrderMemo("测试备注") // TODO 芋艿,后面补充
.setOrderDescription("测试描述") // TODO 芋艿,后面补充
);
// 更新
tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayTransactionId(payTransactionId));
}
private String generateTradeOrderNo() {
// wx
// 2014
// 10
// 27
// 20
// 09
// 39
// 5522657
// a690389285100
// 目前的算法
// 时间序列,年月日时分秒 14 位
// 纯随机6 位 TODO 此处估计是会有问题的,后续在调整
return DateUtil.format(new Date(), "yyyyMMddHHmmss") + // 时间序列
MathUtil.random(100000, 999999) // 随机。为什么是这个范围,因为偷懒
;
}
@Override
public TradeOrderRespDTO getTradeOrder(Integer tradeOrderId, Collection<String> fields) {
// 查询交易订单
TradeOrderDO tradeOrderDO = tradeOrderMapper.selectById(tradeOrderId);
if (tradeOrderDO == null) {
return null;
}
TradeOrderRespDTO tradeOrderRespDTO = TradeOrderConvert.INSTANCE.convert(tradeOrderDO);
// 查询交易订单项
if (fields.contains(TradeOrderDetailFieldEnum.ITEM.getField())) {
List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectListByOrderIds(
Collections.singleton(tradeOrderDO.getId()));
tradeOrderRespDTO.setOrderItems(TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOs));
}
// 返回
return tradeOrderRespDTO;
}
@Override
public PageResult<TradeOrderRespDTO> pageTradeOrder(TradeOrderPageReqDTO pageReqDTO) {
// 查询交易订单分页
IPage<TradeOrderDO> tradeOrderDOPage = tradeOrderMapper.selectPage(pageReqDTO);
PageResult<TradeOrderRespDTO> pageResult = TradeOrderConvert.INSTANCE.convertPage(tradeOrderDOPage);
if (CollectionUtils.isEmpty(pageResult.getList())) {
return pageResult;
}
// 查询交易订单项们
if (pageReqDTO.getFields().contains(TradeOrderDetailFieldEnum.ITEM.getField())) {
List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectListByOrderIds(
convertSet(tradeOrderDOPage.getRecords(), TradeOrderDO::getId));
Map<Integer, List<TradeOrderItemDO>> tradeOrderItemDOMultiMap = CollectionUtils.convertMultiMap(
tradeOrderItemDOs, TradeOrderItemDO::getOrderId);
pageResult.getList().forEach(tradeOrderRespDTO -> tradeOrderRespDTO.setOrderItems(
TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOMultiMap.get(tradeOrderRespDTO.getId()))));
}
// 返回
return pageResult;
}
@Override
@Transactional
public void updateTradeOrderPaySuccess(Integer tradeOrderId, Integer payAmount) {
// if (true) {
// throw new IllegalArgumentException("测试失败的情况");
// }
// 校验交易订单,是否可以
TradeOrderDO tradeOrderDO = tradeOrderMapper.selectById(tradeOrderId);
if (tradeOrderDO == null) { // 订单不存在
throw ServiceExceptionUtil.exception(ORDER_NOT_EXISTENT);
}
if (!tradeOrderDO.getOrderStatus().equals(TradeOrderStatusEnum.WAITING_PAYMENT.getValue())) { // 状态不处于等待支付
throw ServiceExceptionUtil.exception(ORDER_STATUS_NOT_WAITING_PAYMENT);
}
if (!tradeOrderDO.getPresentPrice().equals(payAmount)) { // 支付金额不正确
throw ServiceExceptionUtil.exception(ORDER_PAY_AMOUNT_ERROR);
}
// 更新 TradeOrderDO 状态为已支付,等待发货
TradeOrderDO updateOrderObj = new TradeOrderDO().setId(tradeOrderId)
.setOrderStatus(TradeOrderStatusEnum.WAIT_SHIPMENT.getValue())
.setPayPrice(payAmount)
.setPayTime(new Date());
int updateCount = tradeOrderMapper.update(updateOrderObj, TradeOrderStatusEnum.WAITING_PAYMENT.getValue());
if (updateCount <= 0) {
throw ServiceExceptionUtil.exception(ORDER_STATUS_NOT_WAITING_PAYMENT);
}
// 更新 TradeOrderItemDO 状态为已支付,等待发货
TradeOrderItemDO updateOrderItemObj = new TradeOrderItemDO()
.setStatus(TradeOrderStatusEnum.WAIT_SHIPMENT.getValue());
tradeOrderItemMapper.updateListByOrderId(updateOrderItemObj, tradeOrderId,
TradeOrderStatusEnum.WAITING_PAYMENT.getValue());
}
}

View File

@@ -1,21 +0,0 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://localhost:3306/mall_trade?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
driver-class-name: com.mysql.jdbc.Driver
username: root
password: zhuyang
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: dev # Nacos 命名空间
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址

View File

@@ -1,32 +0,0 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://localhost:3306/mall_trade?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
driver-class-name: com.mysql.jdbc.Driver
username: root
password: zhuyang
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: dev # Nacos 命名空间
# # Spring 主应用配置
# main:
# lazy-initialization: true # 开启延迟加载,保证本地开发的性能
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
# Dubbo 服务提供者的配置
provider:
tag: ${DUBBO_TAG} # Dubbo 路由分组
# MyBatis Plus 配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 本地开发环境下,多打印 SQL 到控制台

View File

@@ -1,75 +0,0 @@
spring:
# Application 的配置项
application:
name: trade-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.tradeservice.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.tradeservice.rpc
# Dubbo 服务提供者的配置
provider:
filter: -exception
validation: true # 开启 Provider 参数校验
version: 1.0.0 # 服务的版本号
# Dubbo 服务消费者的配置
consumer:
ErrorCodeRpc:
version: 1.0.0
ProductSkuRpc:
version: 1.0.0
UserAddressRpc:
version: 1.0.0
PriceRpc:
version: 1.0.0
CouponCardRpc:
version: 1.0.0
PayTransactionRpc:
version: 1.0.0
# RocketMQ 配置项
rocketmq:
name-server: localhost: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.tradeservice.enums.OrderErrorCodeConstants
# 业务配置
biz:
pay-app-id: POd4RC6a
pay-expire-time: 120