Commit 01d10b518c79932b0e76f16ca163d87b22a85fec

Authored by YunaiV
1 parent d7a1c8f7

trade:优化创建订单接口的后端实现

Showing 17 changed files with 310 additions and 139 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java
1 package cn.iocoder.yudao.module.product.api.spu; 1 package cn.iocoder.yudao.module.product.api.spu;
2 2
3 -import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO; 3 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
4 4
5 import java.util.Collection; 5 import java.util.Collection;
6 import java.util.List; 6 import java.util.List;
@@ -19,6 +19,6 @@ public interface ProductSpuApi { @@ -19,6 +19,6 @@ public interface ProductSpuApi {
19 * @param ids SPU 编号列表 19 * @param ids SPU 编号列表
20 * @return SPU 数组 20 * @return SPU 数组
21 */ 21 */
22 - List<SpuInfoRespDTO> getSpuList(Collection<Long> ids); 22 + List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
23 23
24 } 24 }
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/SpuInfoRespDTO.java renamed to yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
@@ -9,11 +9,13 @@ import java.util.List; @@ -9,11 +9,13 @@ import java.util.List;
9 9
10 // TODO @LeeYan9: ProductSpuRespDTO 10 // TODO @LeeYan9: ProductSpuRespDTO
11 /** 11 /**
  12 + * 商品 SPU 信息 Response DTO
  13 + *
12 * @author LeeYan9 14 * @author LeeYan9
13 * @since 2022-08-26 15 * @since 2022-08-26
14 */ 16 */
15 @Data 17 @Data
16 -public class SpuInfoRespDTO { 18 +public class ProductSpuRespDTO {
17 19
18 /** 20 /**
19 * 商品 SPU 编号,自增 21 * 商品 SPU 编号,自增
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
1 package cn.iocoder.yudao.module.product.api.spu; 1 package cn.iocoder.yudao.module.product.api.spu;
2 2
3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 3 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 -import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO; 4 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; 5 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
6 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 6 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
7 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; 7 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
@@ -27,7 +27,7 @@ public class ProductSpuApiImpl implements ProductSpuApi { @@ -27,7 +27,7 @@ public class ProductSpuApiImpl implements ProductSpuApi {
27 private ProductSpuMapper productSpuMapper; 27 private ProductSpuMapper productSpuMapper;
28 28
29 @Override 29 @Override
30 - public List<SpuInfoRespDTO> getSpuList(Collection<Long> spuIds) { 30 + public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
31 // TODO TODO LeeYan9: AllEmpty? 31 // TODO TODO LeeYan9: AllEmpty?
32 if (CollectionUtils.isAnyEmpty(spuIds)) { 32 if (CollectionUtils.isAnyEmpty(spuIds)) {
33 return Collections.emptyList(); 33 return Collections.emptyList();
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
1 package cn.iocoder.yudao.module.product.convert.spu; 1 package cn.iocoder.yudao.module.product.convert.spu;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO; 4 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; 5 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
6 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; 6 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
7 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; 7 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
@@ -35,7 +35,7 @@ public interface ProductSpuConvert { @@ -35,7 +35,7 @@ public interface ProductSpuConvert {
35 35
36 AppSpuPageRespVO convertAppResp(ProductSpuDO list); 36 AppSpuPageRespVO convertAppResp(ProductSpuDO list);
37 37
38 - List<SpuInfoRespDTO> convertList2(List<ProductSpuDO> list); 38 + List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
39 39
40 List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list); 40 List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
41 41
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -22,17 +22,17 @@ public interface ErrorCodeConstants { @@ -22,17 +22,17 @@ public interface ErrorCodeConstants {
22 22
23 // ========== Coupon 相关 1003003000 ============ 23 // ========== Coupon 相关 1003003000 ============
24 ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); 24 ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!");
25 - ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "不满足优惠劵使用的最低金额"); 25 + ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "所结算的商品中未满足使用的金额");
26 26
27 // ========== 优惠劵模板 1003004000 ========== 27 // ========== 优惠劵模板 1003004000 ==========
28 ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在"); 28 ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在");
29 ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})"); 29 ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})");
30 30
31 // ========== 优惠劵模板 1003005000 ========== 31 // ========== 优惠劵模板 1003005000 ==========
32 - ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠劵不存在"); 32 + ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠券不存在");
33 ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用"); 33 ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用");
34 ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态"); 34 ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态");
35 - ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1006003004, "优惠劵不在有效期内"); 35 + ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1006003004, "优惠券不在使用时间范围内");
36 36
37 // ========== 满减送活动 1003006000 ========== 37 // ========== 满减送活动 1003006000 ==========
38 ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在"); 38 ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在");
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java
@@ -116,7 +116,8 @@ public class PriceServiceImpl implements PriceService { @@ -116,7 +116,8 @@ public class PriceServiceImpl implements PriceService {
116 assert originPrice != null; 116 assert originPrice != null;
117 if (originPrice < coupon.getUsePrice()) { 117 if (originPrice < coupon.getUsePrice()) {
118 return couponMeetRespDTO.setMeet(false) 118 return couponMeetRespDTO.setMeet(false)
119 - .setMeetTip(String.format("差 %s 元可用优惠劵", formatPrice(coupon.getUsePrice() - originPrice))); 119 +// .setMeetTip(String.format("差 %s 元可用优惠劵", formatPrice(coupon.getUsePrice() - originPrice)));
  120 + .setMeetTip("所结算的商品中未满足使用的金额");
120 } 121 }
121 } catch (ServiceException serviceException) { 122 } catch (ServiceException serviceException) {
122 couponMeetRespDTO.setMeet(false); 123 couponMeetRespDTO.setMeet(false);
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -12,10 +12,12 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; @@ -12,10 +12,12 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
12 public interface ErrorCodeConstants { 12 public interface ErrorCodeConstants {
13 13
14 // ========== Order 模块 1-011-000-000 ========== 14 // ========== Order 模块 1-011-000-000 ==========
15 - ErrorCode ORDER_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品不存在");  
16 - ErrorCode ORDER_SPU_NOT_SALE = new ErrorCode(1011000002, "商品不可售卖");  
17 - ErrorCode ORDER_SKU_NOT_SALE = new ErrorCode(1011000003, "商品Sku不可售卖");  
18 - ErrorCode ORDER_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品库存不足"); 15 + ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在");
  16 + ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖");
  17 + ErrorCode ORDER_CREATE_SKU_NOT_SALE = new ErrorCode(1011000003, "商品 SKU 不可售卖");
  18 + ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足");
  19 + ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖");
  20 + ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在");
19 21
20 // ========== Cart 模块 1-011-001-000 ========== 22 // ========== Cart 模块 1-011-001-000 ==========
21 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1001001000, "购物车项不存在"); 23 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1001001000, "购物车项不存在");
yudao-module-mall/yudao-module-trade-biz/pom.xml
@@ -29,18 +29,21 @@ @@ -29,18 +29,21 @@
29 <artifactId>yudao-module-product-api</artifactId> 29 <artifactId>yudao-module-product-api</artifactId>
30 <version>${revision}</version> 30 <version>${revision}</version>
31 </dependency> 31 </dependency>
32 -  
33 <dependency> 32 <dependency>
34 <groupId>cn.iocoder.boot</groupId> 33 <groupId>cn.iocoder.boot</groupId>
35 <artifactId>yudao-module-pay-api</artifactId> 34 <artifactId>yudao-module-pay-api</artifactId>
36 <version>${revision}</version> 35 <version>${revision}</version>
37 </dependency> 36 </dependency>
38 -  
39 <dependency> 37 <dependency>
40 <groupId>cn.iocoder.boot</groupId> 38 <groupId>cn.iocoder.boot</groupId>
41 <artifactId>yudao-module-promotion-api</artifactId> 39 <artifactId>yudao-module-promotion-api</artifactId>
42 <version>${revision}</version> 40 <version>${revision}</version>
43 </dependency> 41 </dependency>
  42 + <dependency>
  43 + <groupId>cn.iocoder.boot</groupId>
  44 + <artifactId>yudao-module-member-api</artifactId>
  45 + <version>${revision}</version>
  46 + </dependency>
44 47
45 <!-- 业务组件 --> 48 <!-- 业务组件 -->
46 <dependency> 49 <dependency>
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
5 import lombok.Data; 5 import lombok.Data;
6 6
7 import javax.validation.constraints.Min; 7 import javax.validation.constraints.Min;
  8 +import javax.validation.constraints.NotEmpty;
8 import javax.validation.constraints.NotNull; 9 import javax.validation.constraints.NotNull;
9 import java.util.List; 10 import java.util.List;
10 11
@@ -14,7 +15,7 @@ public class AppTradeOrderCreateReqVO { @@ -14,7 +15,7 @@ public class AppTradeOrderCreateReqVO {
14 15
15 @ApiModelProperty(name = "收件地址编号", required = true, example = "1") 16 @ApiModelProperty(name = "收件地址编号", required = true, example = "1")
16 @NotNull(message = "收件地址不能为空") 17 @NotNull(message = "收件地址不能为空")
17 - private Integer addressId; 18 + private Long addressId;
18 19
19 @ApiModelProperty(name = "优惠劵编号", example = "1024") 20 @ApiModelProperty(name = "优惠劵编号", example = "1024")
20 private Long couponId; 21 private Long couponId;
@@ -29,7 +30,7 @@ public class AppTradeOrderCreateReqVO { @@ -29,7 +30,7 @@ public class AppTradeOrderCreateReqVO {
29 /** 30 /**
30 * 订单商品项列表 31 * 订单商品项列表
31 */ 32 */
32 - @NotNull(message = "必须选择购买的商品") 33 + @NotEmpty(message = "必须选择购买的商品")
33 private List<Item> items; 34 private List<Item> items;
34 35
35 @ApiModel(value = "订单商品项") 36 @ApiModel(value = "订单商品项")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
1 package cn.iocoder.yudao.module.trade.convert.order; 1 package cn.iocoder.yudao.module.trade.convert.order;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  5 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
3 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; 6 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
4 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; 7 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
5 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 8 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  9 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
  10 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemRefundStatusEnum;
6 import org.mapstruct.Mapper; 11 import org.mapstruct.Mapper;
7 import org.mapstruct.Mapping; 12 import org.mapstruct.Mapping;
8 import org.mapstruct.Mappings; 13 import org.mapstruct.Mappings;
9 import org.mapstruct.factory.Mappers; 14 import org.mapstruct.factory.Mappers;
10 15
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  20 +
11 @Mapper 21 @Mapper
12 public interface TradeOrderConvert { 22 public interface TradeOrderConvert {
13 23
14 TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class); 24 TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);
15 25
16 @Mappings({ 26 @Mappings({
17 - @Mapping(source = "order.couponId", target = "couponId"), 27 + @Mapping(source = "createReqVO.couponId", target = "couponId"),
18 @Mapping(target = "remark", ignore = true), 28 @Mapping(target = "remark", ignore = true),
19 - @Mapping(source = "createVO.remark", target = "userRemark"),  
20 - @Mapping(source = "createVO.addressId", target = "receiverAreaId") 29 + @Mapping(source = "createReqVO.remark", target = "userRemark"),
  30 + @Mapping(source = "address.name", target = "receiverName"),
  31 + @Mapping(source = "address.mobile", target = "receiverMobile"),
  32 + @Mapping(source = "address.areaId", target = "receiverAreaId"),
  33 + @Mapping(source = "address.postCode", target = "receiverPostCode"),
  34 + @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"),
  35 + })
  36 + TradeOrderDO convert(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
  37 + PriceCalculateRespDTO.Order order, AddressRespDTO address);
  38 +
  39 + @Mappings({
  40 + @Mapping(target = "id", ignore = true),
  41 + @Mapping(source = "sku.spuId", target = "spuId"),
21 }) 42 })
22 - TradeOrderDO convert(AppTradeOrderCreateReqVO createVO, PriceCalculateRespDTO.Order order); 43 + TradeOrderItemDO convert(PriceCalculateRespDTO.OrderItem orderItem, ProductSkuRespDTO sku);
  44 +
  45 + default List<TradeOrderItemDO> convertList(TradeOrderDO tradeOrderDO,
  46 + List<PriceCalculateRespDTO.OrderItem> orderItems, List<ProductSkuRespDTO> skus) {
  47 + Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId);
  48 + return CollectionUtils.convertList(orderItems, orderItem -> {
  49 + TradeOrderItemDO tradeOrderItemDO = convert(orderItem, skuMap.get(orderItem.getSkuId()));
  50 + tradeOrderItemDO.setOrderId(tradeOrderDO.getId());
  51 + tradeOrderItemDO.setUserId(tradeOrderDO.getUserId());
  52 + tradeOrderItemDO.setRefundStatus(TradeOrderItemRefundStatusEnum.NONE.getStatus());
  53 +// tradeOrderItemDO.setCommented(false);
  54 + return tradeOrderItemDO;
  55 + });
  56 + }
23 57
24 } 58 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java deleted
1 -package cn.iocoder.yudao.module.trade.convert.order;  
2 -  
3 -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;  
4 -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;  
5 -import org.mapstruct.Mapper;  
6 -import org.mapstruct.factory.Mappers;  
7 -  
8 -import java.util.List;  
9 -  
10 -@Mapper  
11 -public interface TradeOrderItemConvert {  
12 -  
13 - TradeOrderItemConvert INSTANCE = Mappers.getMapper(TradeOrderItemConvert.class);  
14 -  
15 - List<TradeOrderItemDO> convertList(List<PriceCalculateRespDTO.OrderItem> items);  
16 -  
17 -}  
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
@@ -70,13 +70,13 @@ public class TradeOrderItemDO extends BaseDO { @@ -70,13 +70,13 @@ public class TradeOrderItemDO extends BaseDO {
70 * 购买数量 70 * 购买数量
71 */ 71 */
72 private Integer count; 72 private Integer count;
73 - /**  
74 - * 是否评论 TODO  
75 - *  
76 - * false - 未评论  
77 - * true - 已评论  
78 - */  
79 - private Boolean commented; 73 +// /**
  74 +// * 是否评论 TODO
  75 +// *
  76 +// * false - 未评论
  77 +// * true - 已评论
  78 +// */
  79 +// private Boolean commented;
80 80
81 // ========== 价格 + 支付基本信息 ========== 81 // ========== 价格 + 支付基本信息 ==========
82 82
@@ -138,19 +138,19 @@ public class TradeOrderItemDO extends BaseDO { @@ -138,19 +138,19 @@ public class TradeOrderItemDO extends BaseDO {
138 * 枚举 {@link TradeOrderItemRefundStatusEnum} 138 * 枚举 {@link TradeOrderItemRefundStatusEnum}
139 */ 139 */
140 private Integer refundStatus; // TODO 芋艿:可以考虑去查 140 private Integer refundStatus; // TODO 芋艿:可以考虑去查
141 - // 如上字段,举个例子:  
142 - // 假设购买三个,即 stock = 3 。  
143 - // originPrice = 15  
144 - // 使用限时折扣(单品优惠)8 折,buyPrice = 12  
145 - // 开始算总的价格  
146 - // buyTotal = buyPrice * stock = 12 * 3 = 36  
147 - // discountTotal ,假设有满减送(分组优惠)满 20 减 10 ,并且使用优惠劵满 1.01 减 1 ,则 discountTotal = 10 + 1 = 11  
148 - // presentTotal = buyTotal - discountTotal = 24 - 11 = 13  
149 - // 最终 presentPrice = presentTotal / stock = 13 / 3 = 4.33  
150 - /**  
151 - * 退款总金额,单位:分 TODO  
152 - */  
153 - private Integer refundTotal; 141 +// // 如上字段,举个例子:
  142 +// // 假设购买三个,即 stock = 3 。
  143 +// // originPrice = 15
  144 +// // 使用限时折扣(单品优惠)8 折,buyPrice = 12
  145 +// // 开始算总的价格
  146 +// // buyTotal = buyPrice * stock = 12 * 3 = 36
  147 +// // discountTotal ,假设有满减送(分组优惠)满 20 减 10 ,并且使用优惠劵满 1.01 减 1 ,则 discountTotal = 10 + 1 = 11
  148 +// // presentTotal = buyTotal - discountTotal = 24 - 11 = 13
  149 +// // 最终 presentPrice = presentTotal / stock = 13 / 3 = 4.33
  150 +// /**
  151 +// * 退款总金额,单位:分 TODO
  152 +// */
  153 +// private Integer refundTotal;
154 154
155 /** 155 /**
156 * 商品属性 156 * 商品属性
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -3,29 +3,27 @@ package cn.iocoder.yudao.module.trade.service.order; @@ -3,29 +3,27 @@ package cn.iocoder.yudao.module.trade.service.order;
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.text.StrBuilder; 4 import cn.hutool.core.text.StrBuilder;
5 import cn.hutool.core.util.IdUtil; 5 import cn.hutool.core.util.IdUtil;
  6 +import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.enums.TerminalEnum; 8 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
8 -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;  
9 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 9 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
10 import cn.iocoder.yudao.framework.common.util.string.StrUtils; 10 import cn.iocoder.yudao.framework.common.util.string.StrUtils;
11 -import cn.iocoder.yudao.module.promotion.api.price.PriceApi;  
12 -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;  
13 -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; 11 +import cn.iocoder.yudao.module.member.api.address.AddressApi;
  12 +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
14 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; 13 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
15 import cn.iocoder.yudao.module.pay.api.order.PayOrderInfoCreateReqDTO; 14 import cn.iocoder.yudao.module.pay.api.order.PayOrderInfoCreateReqDTO;
16 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 15 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
17 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 16 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
18 -import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;  
19 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 17 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
20 -import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO; 18 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
21 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 19 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  20 +import cn.iocoder.yudao.module.promotion.api.price.PriceApi;
  21 +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
  22 +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
22 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; 23 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
23 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item; 24 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item;
24 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; 25 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
25 -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderItemConvert;  
26 -import cn.iocoder.yudao.module.trade.convert.pay.PayOrderConvert;  
27 import cn.iocoder.yudao.module.trade.convert.price.PriceConvert; 26 import cn.iocoder.yudao.module.trade.convert.price.PriceConvert;
28 -import cn.iocoder.yudao.module.trade.convert.sku.ProductSkuConvert;  
29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 27 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
30 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 28 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
31 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; 29 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
@@ -43,6 +41,12 @@ import javax.annotation.Resource; @@ -43,6 +41,12 @@ import javax.annotation.Resource;
43 import java.util.List; 41 import java.util.List;
44 import java.util.Map; 42 import java.util.Map;
45 import java.util.Objects; 43 import java.util.Objects;
  44 +import java.util.Set;
  45 +
  46 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  47 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  48 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_SKU_NOT_SALE;
  49 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_SPU_NOT_FOUND;
46 50
47 /** 51 /**
48 * 交易订单 Service 实现类 52 * 交易订单 Service 实现类
@@ -70,66 +74,51 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -70,66 +74,51 @@ public class TradeOrderServiceImpl implements TradeOrderService {
70 private ProductSpuApi productSpuApi; 74 private ProductSpuApi productSpuApi;
71 @Resource 75 @Resource
72 private PayOrderApi payOrderApi; 76 private PayOrderApi payOrderApi;
  77 + @Resource
  78 + private AddressApi addressApi;
73 79
74 @Resource 80 @Resource
75 private TradeOrderProperties tradeOrderProperties; 81 private TradeOrderProperties tradeOrderProperties;
76 82
77 @Override 83 @Override
78 @Transactional(rollbackFor = Exception.class) 84 @Transactional(rollbackFor = Exception.class)
79 - public Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO) {  
80 - List<Item> items = createReqVO.getItems();  
81 - // 商品SKU检查 sku可售状态,库存  
82 - List<ProductSkuRespDTO> skuInfos = productSkuApi.getSkuList(CollectionUtils.convertSet(items, Item::getSkuId));  
83 - Map<Long, ProductSkuRespDTO> skuInfoMap = CollectionUtils.convertMap(skuInfos, ProductSkuRespDTO::getId);  
84 - checkSaleableAndStockFromSpu(skuInfoMap, items);  
85 -  
86 - // 商品SPU检查 sku可售状态,库存  
87 - List<SpuInfoRespDTO> spuInfos = productSpuApi.getSpuList(CollectionUtils.convertSet(skuInfos, ProductSkuRespDTO::getSpuId));  
88 - checkSaleableFromSpu(spuInfos); 85 + public Long createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO) {
  86 + // 商品 SKU 检查:可售状态、库存
  87 + List<ProductSkuRespDTO> skus = validateSkuSaleable(createReqVO.getItems());
  88 + // 商品 SPU 检查:可售状态
  89 + List<ProductSpuRespDTO> spus = validateSpuSaleable(convertSet(skus, ProductSkuRespDTO::getSpuId));
  90 + // 用户收件地址的校验
  91 + AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId());
89 92
90 // 价格计算 93 // 价格计算
91 - PriceCalculateReqDTO priceCalculateReqDTO = PriceConvert.INSTANCE.convert(createReqVO, loginUserId); 94 + PriceCalculateReqDTO priceCalculateReqDTO = PriceConvert.INSTANCE.convert(createReqVO, userId);
92 PriceCalculateRespDTO priceResp = priceApi.calculatePrice(priceCalculateReqDTO); 95 PriceCalculateRespDTO priceResp = priceApi.calculatePrice(priceCalculateReqDTO);
93 - // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!  
94 96
95 - // 订单信息记录  
96 - TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(createReqVO, priceResp.getOrder());  
97 - fillTradeOrderInfoFromReqInfo(tradeOrderDO,createReqVO,loginUserId, clientIp); // TODO @LeeYan9: tradeOrderDO, createReqVO, loginUserId, clientIp  
98 - tradeOrderMapper.insert(tradeOrderDO); 97 + // 插入 TradeOrderDO 订单
  98 + TradeOrderDO tradeOrderDO = createTradeOrder(userId, clientIp, createReqVO, priceResp.getOrder(), address);
  99 + // 插入 TradeOrderItemDO 订单项
  100 + createTradeOrderItems(tradeOrderDO, priceResp.getOrder().getItems(), skus);
  101 +
  102 + // 下单时扣减商品库存 TODO
  103 +// List<SkuDecrementStockBatchReqDTO.Item> skuDecrementStockItems = ProductSkuConvert.INSTANCE.convert(tradeOrderItems);
  104 +// productSkuApi.decrementStockBatch(SkuDecrementStockBatchReqDTO.of(skuDecrementStockItems));
  105 +
  106 + // 删除购物车商品 TODO 芋艿:待实现
99 107
100 - // 订单项信息记录  
101 - List<TradeOrderItemDO> tradeOrderItems = TradeOrderItemConvert.INSTANCE.convertList(priceResp.getOrder().getItems());  
102 - // 填充订单项-SKU信息  
103 - fillItemsInfoFromSkuAndOrder(tradeOrderDO, tradeOrderItems, skuInfoMap);  
104 - tradeOrderItemMapper.insertBatch(tradeOrderItems); 108 + // 扣减积分,抵扣金额 TODO 芋艿:待实现
105 109
106 - // TODO @LeeYan9: 先扣减库存哈; 可能会扣减失败; 毕竟 get 和 update 之间, 会有并发的可能性  
107 - // 库存扣减  
108 - List<SkuDecrementStockBatchReqDTO.Item> skuDecrementStockItems = ProductSkuConvert.INSTANCE.convert(tradeOrderItems);  
109 - productSkuApi.decrementStockBatch(SkuDecrementStockBatchReqDTO.of(skuDecrementStockItems)); 110 + // 有使用优惠券时更新
  111 +
  112 + // 增加订单日志 TODO 芋艿:待实现
110 113
111 // 构建预支付请求参数 114 // 构建预支付请求参数
112 // TODO @LeeYan9: 需要更新到订单上 115 // TODO @LeeYan9: 需要更新到订单上
113 - PayOrderInfoCreateReqDTO payOrderCreateReqDTO = PayOrderConvert.INSTANCE.convert(tradeOrderDO);  
114 - fillPayOrderInfoFromItems(payOrderCreateReqDTO, tradeOrderItems); 116 +// PayOrderInfoCreateReqDTO payOrderCreateReqDTO = PayOrderConvert.INSTANCE.convert(tradeOrderDO);
  117 +// fillPayOrderInfoFromItems(payOrderCreateReqDTO, tradeOrderItems);
115 // 生成预支付 118 // 生成预支付
116 - return payOrderApi.createPayOrder(payOrderCreateReqDTO);  
117 - }  
118 -  
119 - // TODO @LeeYan9: 填充就好, 不用 from 哈;  
120 - private void fillTradeOrderInfoFromReqInfo(TradeOrderDO tradeOrderDO, AppTradeOrderCreateReqVO createReqVO,  
121 - Long loginUserId, String clientIp) {  
122 - tradeOrderDO.setUserId(loginUserId);  
123 - tradeOrderDO.setUserIp(clientIp);  
124 - tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的;  
125 - tradeOrderDO.setStatus(TradeOrderStatusEnum.WAITING_PAYMENT.getStatus());  
126 - tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType());  
127 - tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());  
128 - tradeOrderDO.setProductCount(CollectionUtils.getSumValue(createReqVO.getItems(), Item::getCount,Integer::sum));  
129 - // todo 地址&用户信息解析  
130 119
131 - // todo 数据来源?  
132 - tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); 120 + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
  121 + return tradeOrderDO.getId();
133 } 122 }
134 123
135 private void fillPayOrderInfoFromItems(PayOrderInfoCreateReqDTO payOrderInfoCreateReqDTO, 124 private void fillPayOrderInfoFromItems(PayOrderInfoCreateReqDTO payOrderInfoCreateReqDTO,
@@ -157,7 +146,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -157,7 +146,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
157 payOrderInfoCreateReqDTO.setBody(StrUtils.maxLength(body.subString(1), 128)); 146 payOrderInfoCreateReqDTO.setBody(StrUtils.maxLength(body.subString(1), 128));
158 } 147 }
159 148
160 - private void fillItemsInfoFromSkuAndOrder(TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> tradeOrderItems, 149 + private void xfillItemsInfoFromSkuAndOrder(TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> tradeOrderItems,
161 Map<Long, ProductSkuRespDTO> spuInfos) { 150 Map<Long, ProductSkuRespDTO> spuInfos) {
162 for (TradeOrderItemDO tradeOrderItem : tradeOrderItems) { 151 for (TradeOrderItemDO tradeOrderItem : tradeOrderItems) {
163 // 填充订单信息 152 // 填充订单信息
@@ -176,32 +165,87 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -176,32 +165,87 @@ public class TradeOrderServiceImpl implements TradeOrderService {
176 } 165 }
177 } 166 }
178 167
179 - private void checkSaleableFromSpu(List<SpuInfoRespDTO> spuInfos) {  
180 - SpuInfoRespDTO spu = CollectionUtils.findFirst(spuInfos,  
181 - spuInfoDTO -> !Objects.equals(ProductSpuStatusEnum.ENABLE.getStatus(), spuInfoDTO.getStatus()));  
182 - if (Objects.isNull(spu)) {  
183 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SPU_NOT_SALE); 168 + /**
  169 + * 校验商品 SKU 是否可出售
  170 + *
  171 + * @param items 商品 SKU
  172 + * @return 商品 SKU 数组
  173 + */
  174 + private List<ProductSkuRespDTO> validateSkuSaleable(List<Item> items) {
  175 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId));
  176 + // SKU 不存在
  177 + if (items.size() != skus.size()) {
  178 + throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_NOT_FOUND);
184 } 179 }
  180 + // 校验是否禁用 or 库存不足
  181 + Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId);
  182 + items.forEach(item -> {
  183 + ProductSkuRespDTO sku = skuMap.get(item.getSkuId());
  184 + // SKU 禁用
  185 + if (ObjectUtil.notEqual(CommonStatusEnum.ENABLE.getStatus(), sku.getStatus())) {
  186 + throw exception(ORDER_CREATE_SKU_NOT_SALE);
  187 + }
  188 + // SKU 库存不足
  189 + if (item.getCount() > sku.getStock()) {
  190 + throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH);
  191 + }
  192 + });
  193 + return skus;
185 } 194 }
186 195
187 - // TODO @LeeYan9: checkSpuXXX 会不会好点哈? ps: 这个貌似是 sku 哈  
188 - private void checkSaleableAndStockFromSpu(Map<Long, ProductSkuRespDTO> skuInfoMap,  
189 - List<Item> items) {  
190 - // sku 不存在  
191 - if (items.size() != skuInfoMap.size()) {  
192 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SKU_NOT_FOUND); 196 + /**
  197 + * 校验商品 SPU 是否可出售
  198 + *
  199 + * @param spuIds 商品 SPU 编号数组
  200 + * @return 商品 SPU 数组
  201 + */
  202 + private List<ProductSpuRespDTO> validateSpuSaleable(Set<Long> spuIds) {
  203 + List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(spuIds);
  204 + // SPU 不存在
  205 + if (spus.size() != spuIds.size()) {
  206 + throw exception(ORDER_CREATE_SPU_NOT_FOUND);
193 } 207 }
194 - for (Item item : items) {  
195 - ProductSkuRespDTO skuInfoDTO = skuInfoMap.get(item.getSkuId());  
196 - // sku禁用  
197 - if (!Objects.equals(CommonStatusEnum.ENABLE.getStatus(), skuInfoDTO.getStatus())) {  
198 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SKU_NOT_SALE);  
199 - }  
200 - // sku库存不足  
201 - if (item.getCount() > skuInfoDTO.getStock()) {  
202 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SKU_STOCK_NOT_ENOUGH);  
203 - } 208 + // 校验是否存在禁用的 SPU
  209 + ProductSpuRespDTO spu = CollectionUtils.findFirst(spus,
  210 + spuDTO -> ObjectUtil.notEqual(ProductSpuStatusEnum.ENABLE.getStatus(), spuDTO.getStatus()));
  211 + if (Objects.isNull(spu)) {
  212 + throw exception(ErrorCodeConstants.ORDER_CREATE_SPU_NOT_SALE);
204 } 213 }
  214 + return spus;
  215 + }
205 216
  217 + /**
  218 + * 校验收件地址是否存在
  219 + *
  220 + * @param userId 用户编号
  221 + * @param addressId 收件地址编号
  222 + * @return 收件地址
  223 + */
  224 + private AddressRespDTO validateAddress(Long userId, Long addressId) {
  225 + AddressRespDTO address = addressApi.getAddress(userId, addressId);
  226 + if (Objects.isNull(address)) {
  227 + throw exception(ErrorCodeConstants.ORDER_CREATE_ADDRESS_NOT_FOUND);
  228 + }
  229 + return address;
206 } 230 }
  231 +
  232 + private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
  233 + PriceCalculateRespDTO.Order order, AddressRespDTO address) {
  234 + TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, order, address);
  235 + tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的;
  236 + tradeOrderDO.setStatus(TradeOrderStatusEnum.WAITING_PAYMENT.getStatus());
  237 + tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType());
  238 + tradeOrderDO.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
  239 + tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum));
  240 + tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源?
  241 + tradeOrderMapper.insert(tradeOrderDO);
  242 + return tradeOrderDO;
  243 + }
  244 +
  245 + private void createTradeOrderItems(TradeOrderDO tradeOrderDO,
  246 + List<PriceCalculateRespDTO.OrderItem> orderItems, List<ProductSkuRespDTO> skus) {
  247 + List<TradeOrderItemDO> tradeOrderItemDOs = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, orderItems, skus);
  248 + tradeOrderItemMapper.insertBatch(tradeOrderItemDOs);
  249 + }
  250 +
207 } 251 }
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.api.address;
  2 +
  3 +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  4 +
  5 +/**
  6 + * 用户收件地址 API 接口
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public interface AddressApi {
  11 +
  12 + /**
  13 + * 获得用户收件地址
  14 + *
  15 + * @param id 收件地址编号
  16 + * @param userId 用户编号
  17 + * @return 用户收件地址
  18 + */
  19 + AddressRespDTO getAddress(Long id, Long userId);
  20 +
  21 +}
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.api.address.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 用户收件地址 Response DTO
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +@Data
  11 +public class AddressRespDTO {
  12 +
  13 + /**
  14 + * 编号
  15 + */
  16 + private Long id;
  17 + /**
  18 + * 用户编号
  19 + */
  20 + private Long userId;
  21 + /**
  22 + * 收件人名称
  23 + */
  24 + private String name;
  25 + /**
  26 + * 手机号
  27 + */
  28 + private String mobile;
  29 + /**
  30 + * 地区编号
  31 + */
  32 + private Long areaId;
  33 + /**
  34 + * 邮编
  35 + */
  36 + private String postCode;
  37 + /**
  38 + * 收件详细地址
  39 + */
  40 + private String detailAddress;
  41 + /**
  42 + * 是否默认
  43 + *
  44 + * true - 默认收件地址
  45 + */
  46 + private Boolean defaulted;
  47 +
  48 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.api.address;
  2 +
  3 +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  4 +import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
  5 +import cn.iocoder.yudao.module.member.service.address.AddressService;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import javax.annotation.Resource;
  10 +
  11 +/**
  12 + * 用户收件地址 API 实现类
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Service
  17 +@Validated
  18 +public class AddressApiImpl implements AddressApi {
  19 +
  20 + @Resource
  21 + private AddressService addressService;
  22 +
  23 + @Override
  24 + public AddressRespDTO getAddress(Long id, Long userId) {
  25 + return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id));
  26 + }
  27 +
  28 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java
1 package cn.iocoder.yudao.module.member.convert.address; 1 package cn.iocoder.yudao.module.member.convert.address;
2 2
3 -import java.util.*;  
4 -  
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 - 4 +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  5 +import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
  6 +import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO;
  7 +import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
  8 +import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
7 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 10 import org.mapstruct.factory.Mappers;
9 -import cn.iocoder.yudao.module.member.controller.app.address.vo.*;  
10 -import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; 11 +
  12 +import java.util.List;
11 13
12 /** 14 /**
13 * 用户收件地址 Convert 15 * 用户收件地址 Convert
@@ -29,4 +31,6 @@ public interface AddressConvert { @@ -29,4 +31,6 @@ public interface AddressConvert {
29 31
30 PageResult<AppAddressRespVO> convertPage(PageResult<AddressDO> page); 32 PageResult<AppAddressRespVO> convertPage(PageResult<AddressDO> page);
31 33
  34 + AddressRespDTO convert02(AddressDO bean);
  35 +
32 } 36 }