Commit 2a9a869e01083b87efcdea0135823f02db4f38e9
1 parent
5de8fa2e
mall + trade:获得订单结算信息,接入支付接口
Showing
21 changed files
with
292 additions
and
180 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
| 1 | 1 | package cn.iocoder.yudao.module.product.api.sku.dto; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | |
| 3 | 4 | import lombok.Data; |
| 4 | 5 | |
| 5 | 6 | import java.util.List; |
| ... | ... | @@ -25,7 +26,7 @@ public class ProductSkuRespDTO { |
| 25 | 26 | /** |
| 26 | 27 | * 属性数组 |
| 27 | 28 | */ |
| 28 | - private List<Property> properties; | |
| 29 | + private List<ProductPropertyValueDetailRespDTO> properties; | |
| 29 | 30 | /** |
| 30 | 31 | * 销售价格,单位:分 |
| 31 | 32 | */ |
| ... | ... | @@ -63,30 +64,4 @@ public class ProductSkuRespDTO { |
| 63 | 64 | */ |
| 64 | 65 | private Double volume; |
| 65 | 66 | |
| 66 | - /** | |
| 67 | - * 商品属性 | |
| 68 | - */ | |
| 69 | - @Data | |
| 70 | - public static class Property { | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * 属性编号 | |
| 74 | - */ | |
| 75 | - private Long propertyId; | |
| 76 | - /** | |
| 77 | - * 属性名字 | |
| 78 | - */ | |
| 79 | - private String propertyName; | |
| 80 | - | |
| 81 | - /** | |
| 82 | - * 属性值编号 | |
| 83 | - */ | |
| 84 | - private Long valueId; | |
| 85 | - /** | |
| 86 | - * 属性值名字 | |
| 87 | - */ | |
| 88 | - private String valueName; | |
| 89 | - | |
| 90 | - } | |
| 91 | - | |
| 92 | 67 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java
| ... | ... | @@ -18,6 +18,9 @@ public class AppProductSpuDetailRespVO { |
| 18 | 18 | @Schema(description = "商品名称", required = true, example = "芋道") |
| 19 | 19 | private String name; |
| 20 | 20 | |
| 21 | + @Schema(description = "商品简介", required = true, example = "我是一个快乐简介") | |
| 22 | + private String introduction; | |
| 23 | + | |
| 21 | 24 | @Schema(description = "商品详情", required = true, example = "我是商品描述") |
| 22 | 25 | private String description; |
| 23 | 26 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java
| ... | ... | @@ -93,7 +93,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 93 | 93 | assertNull(promotion.getId()); |
| 94 | 94 | assertEquals(promotion.getName(), "会员折扣"); |
| 95 | 95 | assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); |
| 96 | - assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); | |
| 97 | 96 | assertEquals(promotion.getTotalPrice(), 200); |
| 98 | 97 | assertEquals(promotion.getDiscountPrice(), 20); |
| 99 | 98 | assertTrue(promotion.getMatch()); |
| ... | ... | @@ -264,7 +263,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 264 | 263 | assertEquals(promotion01.getId(), 1000L); |
| 265 | 264 | assertEquals(promotion01.getName(), "活动 1000 号"); |
| 266 | 265 | assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); |
| 267 | - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); | |
| 268 | 266 | assertEquals(promotion01.getTotalPrice(), 350); |
| 269 | 267 | assertEquals(promotion01.getDiscountPrice(), 70); |
| 270 | 268 | assertTrue(promotion01.getMatch()); |
| ... | ... | @@ -283,7 +281,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 283 | 281 | assertEquals(promotion02.getId(), 2000L); |
| 284 | 282 | assertEquals(promotion02.getName(), "活动 2000 号"); |
| 285 | 283 | assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); |
| 286 | - assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); | |
| 287 | 284 | assertEquals(promotion02.getTotalPrice(), 120); |
| 288 | 285 | assertEquals(promotion02.getDiscountPrice(), 60); |
| 289 | 286 | assertTrue(promotion02.getMatch()); |
| ... | ... | @@ -352,7 +349,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 352 | 349 | assertEquals(promotion01.getId(), 1000L); |
| 353 | 350 | assertEquals(promotion01.getName(), "活动 1000 号"); |
| 354 | 351 | assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); |
| 355 | - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); | |
| 356 | 352 | assertEquals(promotion01.getTotalPrice(), 350); |
| 357 | 353 | assertEquals(promotion01.getDiscountPrice(), 0); |
| 358 | 354 | assertFalse(promotion01.getMatch()); |
| ... | ... | @@ -434,7 +430,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 434 | 430 | assertEquals(promotion01.getId(), 1024L); |
| 435 | 431 | assertEquals(promotion01.getName(), "程序员节"); |
| 436 | 432 | assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); |
| 437 | - assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); | |
| 438 | 433 | assertEquals(promotion01.getTotalPrice(), 350); |
| 439 | 434 | assertEquals(promotion01.getDiscountPrice(), 70); |
| 440 | 435 | assertTrue(promotion01.getMatch()); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
| 1 | -### /trade-order/settlement 获得订单结算信息 | |
| 2 | -GET {{appApi}}/trade/order/settlement?cartIds=1 | |
| 1 | +### /trade-order/settlement 获得订单结算信息(基于商品) | |
| 2 | +GET {{appApi}}/trade/order/settlement?type=0&items[0].skuId=1&items[0].count=2&items[1].skuId=2&items[1].count=3&couponId=1 | |
| 3 | +Authorization: Bearer {{appToken}} | |
| 4 | +tenant-id: {{appTenentId}} | |
| 5 | + | |
| 6 | +### /trade-order/settlement 获得订单结算信息(基于购物车) | |
| 7 | +GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 | |
| 3 | 8 | Authorization: Bearer {{appToken}} |
| 4 | 9 | tenant-id: {{appTenentId}} |
| 5 | 10 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
| ... | ... | @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 6 | 6 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; |
| 7 | 7 | import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; |
| 8 | 8 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 9 | -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; | |
| 10 | 9 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; |
| 11 | 10 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; |
| 12 | 11 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; |
| ... | ... | @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.*; |
| 25 | 24 | import javax.annotation.Resource; |
| 26 | 25 | import javax.servlet.http.HttpServletRequest; |
| 27 | 26 | import javax.validation.Valid; |
| 28 | -import java.util.ArrayList; | |
| 29 | 27 | import java.util.HashMap; |
| 30 | 28 | import java.util.List; |
| 31 | 29 | import java.util.Map; |
| ... | ... | @@ -53,78 +51,8 @@ public class AppTradeOrderController { |
| 53 | 51 | @GetMapping("/settlement") |
| 54 | 52 | @Operation(summary = "获得订单结算信息") |
| 55 | 53 | @PreAuthenticated |
| 56 | - public CommonResult<AppTradeOrderSettlementRespVO> settlementOrder( | |
| 57 | - @Valid AppTradeOrderSettlementReqVO settlementReqVO) { | |
| 58 | - if (true) { | |
| 59 | - return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO)); | |
| 60 | - } | |
| 61 | -// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); | |
| 62 | - AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO(); | |
| 63 | - | |
| 64 | - AppTradeOrderSettlementRespVO.Price price = new AppTradeOrderSettlementRespVO.Price(); | |
| 65 | - price.setTotalPrice(1000); | |
| 66 | - price.setDeliveryPrice(200); | |
| 67 | - price.setCouponPrice(100); | |
| 68 | - price.setPointPrice(50); | |
| 69 | - price.setPayPrice(950); | |
| 70 | - | |
| 71 | - List<AppTradeOrderSettlementRespVO.Item> skus = new ArrayList<>(); | |
| 72 | - | |
| 73 | - AppTradeOrderSettlementRespVO.Item item1 = new AppTradeOrderSettlementRespVO.Item(); | |
| 74 | - item1.setCartId(1L); | |
| 75 | - item1.setSpuId(2048L); | |
| 76 | - item1.setSpuName("Apple iPhone 12"); | |
| 77 | - item1.setSkuId(1024); | |
| 78 | - item1.setPrice(500); | |
| 79 | - item1.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); | |
| 80 | - item1.setCount(2); | |
| 81 | - List<AppProductPropertyValueDetailRespVO> properties1 = new ArrayList<>(); | |
| 82 | - AppProductPropertyValueDetailRespVO property1 = new AppProductPropertyValueDetailRespVO(); | |
| 83 | - property1.setPropertyId(1L); | |
| 84 | - property1.setPropertyName("尺寸"); | |
| 85 | - property1.setValueId(2L); | |
| 86 | - property1.setValueName("大"); | |
| 87 | - properties1.add(property1); | |
| 88 | - item1.setProperties(properties1); | |
| 89 | - | |
| 90 | - AppTradeOrderSettlementRespVO.Item item2 = new AppTradeOrderSettlementRespVO.Item(); | |
| 91 | - item2.setCartId(2L); | |
| 92 | - item2.setSpuId(3072L); | |
| 93 | - item2.setSpuName("Samsung Galaxy S21"); | |
| 94 | - item2.setSkuId(2048); | |
| 95 | - item2.setPrice(800); | |
| 96 | - item2.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg"); | |
| 97 | - item2.setCount(1); | |
| 98 | - List<AppProductPropertyValueDetailRespVO> properties2 = new ArrayList<>(); | |
| 99 | - AppProductPropertyValueDetailRespVO property2 = new AppProductPropertyValueDetailRespVO(); | |
| 100 | - property2.setPropertyId(10L); | |
| 101 | - property2.setPropertyName("颜色"); | |
| 102 | - property2.setValueId(20L); | |
| 103 | - property2.setValueName("白色"); | |
| 104 | - properties2.add(property2); | |
| 105 | - item2.setProperties(properties2); | |
| 106 | - | |
| 107 | - skus.add(item1); | |
| 108 | - skus.add(item2); | |
| 109 | - | |
| 110 | - settlement.setItems(skus); | |
| 111 | - settlement.setPrice(price); | |
| 112 | - | |
| 113 | - AppTradeOrderSettlementRespVO.Address address = new AppTradeOrderSettlementRespVO.Address(); | |
| 114 | - address.setId(1L); | |
| 115 | - address.setName("John"); | |
| 116 | - address.setMobile("18888888888"); | |
| 117 | - address.setProvinceId(1L); | |
| 118 | - address.setProvinceName("Beijing"); | |
| 119 | - address.setCityId(1L); | |
| 120 | - address.setCityName("Beijing"); | |
| 121 | - address.setDistrictId(1L); | |
| 122 | - address.setDistrictName("Chaoyang Distripct"); | |
| 123 | - address.setDetailAddress("No. 10, Xinzhong Street, Chaoyang District"); | |
| 124 | - address.setDefaulted(true); | |
| 125 | - settlement.setAddress(address); | |
| 126 | - | |
| 127 | - return success(settlement); | |
| 54 | + public CommonResult<AppTradeOrderSettlementRespVO> settlementOrder(@Valid AppTradeOrderSettlementReqVO settlementReqVO) { | |
| 55 | + return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO)); | |
| 128 | 56 | } |
| 129 | 57 | |
| 130 | 58 | @PostMapping("/create") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.controller.app.order.vo; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | |
| 5 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
| 3 | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 7 | import lombok.Data; |
| 5 | 8 | |
| 6 | -import javax.validation.constraints.NotEmpty; | |
| 9 | +import javax.validation.Valid; | |
| 10 | +import javax.validation.constraints.AssertTrue; | |
| 11 | +import javax.validation.constraints.Min; | |
| 12 | +import javax.validation.constraints.NotNull; | |
| 7 | 13 | import java.util.List; |
| 8 | 14 | |
| 9 | 15 | @Schema(description = "用户 App - 交易订单结算 Request VO") |
| 10 | 16 | @Data |
| 11 | 17 | public class AppTradeOrderSettlementReqVO { |
| 12 | 18 | |
| 19 | + @NotNull(message = "交易类型不能为空") | |
| 20 | + @InEnum(value = TradeOrderTypeEnum.class, message = "交易类型必须是 {value}") | |
| 21 | + private Integer type; | |
| 22 | + | |
| 23 | + @Schema(description = "商品项数组", required = true) | |
| 24 | + @NotNull(message = "商品不能为空") | |
| 25 | + private List<Item> items; | |
| 26 | + | |
| 13 | 27 | @Schema(description = "收件地址编号", example = "1") |
| 14 | 28 | private Long addressId; |
| 15 | 29 | |
| 16 | 30 | @Schema(description = "优惠劵编号", example = "1024") |
| 17 | 31 | private Long couponId; |
| 18 | 32 | |
| 19 | - @Schema(description = "购物车项的编号数组", required = true, example = "true") | |
| 20 | - @NotEmpty(message = "购物车项不能为空") | |
| 21 | - private List<Long> cartIds; | |
| 33 | + @Data | |
| 34 | + @Schema(description = "用户 App - 商品项") | |
| 35 | + @Valid | |
| 36 | + public static class Item { | |
| 37 | + | |
| 38 | + @Schema(description = "商品 SKU 编号", example = "2048") | |
| 39 | + private Long skuId; | |
| 40 | + @Schema(description = "购买数量", example = "1") | |
| 41 | + @Min(value = 1, message = "购买数量最小值为 {value}") | |
| 42 | + private Integer count; | |
| 43 | + | |
| 44 | + @Schema(description = "购物车项的编号", example = "1024") | |
| 45 | + private Long cartId; | |
| 46 | + | |
| 47 | + @AssertTrue(message = "商品不正确") | |
| 48 | + @JsonIgnore | |
| 49 | + public boolean isValid() { | |
| 50 | + // 组合一:skuId + count 使用商品 SKU | |
| 51 | + if (skuId != null && count != null) { | |
| 52 | + return true; | |
| 53 | + } | |
| 54 | + // 组合二:cartId 使用购物车项 | |
| 55 | + return cartId != null; | |
| 56 | + } | |
| 57 | + | |
| 58 | + } | |
| 22 | 59 | |
| 23 | 60 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java
| ... | ... | @@ -91,17 +91,17 @@ public class AppTradeOrderSettlementRespVO { |
| 91 | 91 | private String mobile; |
| 92 | 92 | |
| 93 | 93 | @Schema(description = "省份编号", required = true, example = "1") |
| 94 | - private Long provinceId; | |
| 94 | + private Integer provinceId; | |
| 95 | 95 | @Schema(description = "省份名字", required = true, example = "北京") |
| 96 | 96 | private String provinceName; |
| 97 | 97 | |
| 98 | 98 | @Schema(description = "城市编号", required = true, example = "1") |
| 99 | - private Long cityId; | |
| 99 | + private Integer cityId; | |
| 100 | 100 | @Schema(description = "城市名字", required = true, example = "北京") |
| 101 | 101 | private String cityName; |
| 102 | 102 | |
| 103 | 103 | @Schema(description = "地区编号", required = true, example = "1") |
| 104 | - private Long districtId; | |
| 104 | + private Integer districtId; | |
| 105 | 105 | @Schema(description = "地区名字", required = true, example = "朝阳区") |
| 106 | 106 | private String districtName; |
| 107 | 107 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.convert.order; |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | +import cn.iocoder.yudao.framework.ip.core.Area; | |
| 6 | 7 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 7 | 8 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; |
| 8 | 9 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| ... | ... | @@ -18,14 +19,15 @@ import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.Prod |
| 18 | 19 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; |
| 19 | 20 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; |
| 20 | 21 | import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; |
| 21 | -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; | |
| 22 | -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO; | |
| 23 | -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO; | |
| 22 | +import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; | |
| 24 | 23 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; |
| 24 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 25 | 25 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 26 | 26 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 27 | 27 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; |
| 28 | 28 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 29 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | |
| 30 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | |
| 29 | 31 | import org.mapstruct.Mapper; |
| 30 | 32 | import org.mapstruct.Mapping; |
| 31 | 33 | import org.mapstruct.Mappings; |
| ... | ... | @@ -241,4 +243,45 @@ public interface TradeOrderConvert { |
| 241 | 243 | |
| 242 | 244 | AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); |
| 243 | 245 | |
| 246 | + default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, | |
| 247 | + List<TradeCartDO> cartList) { | |
| 248 | + TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); | |
| 249 | + reqBO.setUserId(userId).setType(settlementReqVO.getType()) | |
| 250 | + .setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) | |
| 251 | + .setItems(new ArrayList<>(settlementReqVO.getItems().size())); | |
| 252 | + // 商品项的构建 | |
| 253 | + Map<Long, TradeCartDO> cartMap = convertMap(cartList, TradeCartDO::getId); | |
| 254 | + for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { | |
| 255 | + // 情况一:skuId + count | |
| 256 | + if (item.getSkuId() != null) { | |
| 257 | + reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(item.getSkuId()).setCount(item.getCount()) | |
| 258 | + .setSelected(true)); // true 的原因,下单一定选中 | |
| 259 | + continue; | |
| 260 | + } | |
| 261 | + // 情况二:cartId | |
| 262 | + TradeCartDO cart = cartMap.get(item.getCartId()); | |
| 263 | + if (cart == null) { | |
| 264 | + continue; | |
| 265 | + } | |
| 266 | + reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(cart.getSkuId()).setCount(cart.getCount()) | |
| 267 | + .setCartId(item.getCartId()).setSelected(true)); // true 的原因,下单一定选中 | |
| 268 | + } | |
| 269 | + return reqBO; | |
| 270 | + } | |
| 271 | + | |
| 272 | + default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, AddressRespDTO address) { | |
| 273 | + AppTradeOrderSettlementRespVO respVO = convert0(calculate, address); | |
| 274 | + if (address != null) { | |
| 275 | + Area area = AreaUtils.getArea(address.getAreaId()); | |
| 276 | + respVO.getAddress().setDistrictId(area.getId()); | |
| 277 | + respVO.getAddress().setDistrictName(area.getName()); | |
| 278 | + respVO.getAddress().setCityId(area.getParent().getId()); | |
| 279 | + respVO.getAddress().setCityName(area.getParent().getName()); | |
| 280 | + respVO.getAddress().setProvinceId(area.getParent().getParent().getId()); | |
| 281 | + respVO.getAddress().setProvinceName(area.getParent().getParent().getName()); | |
| 282 | + } | |
| 283 | + return respVO; | |
| 284 | + } | |
| 285 | + AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address); | |
| 286 | + | |
| 244 | 287 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartMapper.java
| ... | ... | @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; |
| 12 | 12 | import java.util.Collection; |
| 13 | 13 | import java.util.List; |
| 14 | 14 | import java.util.Map; |
| 15 | +import java.util.Set; | |
| 15 | 16 | |
| 16 | 17 | @Mapper |
| 17 | 18 | public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { |
| ... | ... | @@ -70,4 +71,10 @@ public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { |
| 70 | 71 | update(updateObject, new LambdaQueryWrapper<TradeCartDO>().in(TradeCartDO::getId, ids)); |
| 71 | 72 | } |
| 72 | 73 | |
| 74 | + default List<TradeCartDO> selectListByUserId(Long userId, Set<Long> ids) { | |
| 75 | + return selectList(new LambdaQueryWrapper<TradeCartDO>() | |
| 76 | + .eq(TradeCartDO::getUserId, userId) | |
| 77 | + .in(TradeCartDO::getId, ids)); | |
| 78 | + } | |
| 79 | + | |
| 73 | 80 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java
| ... | ... | @@ -4,10 +4,13 @@ import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO |
| 4 | 4 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; |
| 5 | 5 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; |
| 6 | 6 | import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; |
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 7 | 8 | |
| 8 | 9 | import javax.validation.Valid; |
| 9 | 10 | import java.util.Collection; |
| 11 | +import java.util.List; | |
| 10 | 12 | import java.util.Map; |
| 13 | +import java.util.Set; | |
| 11 | 14 | |
| 12 | 15 | /** |
| 13 | 16 | * 购物车 Service 接口 |
| ... | ... | @@ -68,6 +71,15 @@ public interface TradeCartService { |
| 68 | 71 | AppTradeCartListRespVO getCartList(Long userId); |
| 69 | 72 | |
| 70 | 73 | /** |
| 74 | + * 查询用户的购物车列表 | |
| 75 | + * | |
| 76 | + * @param userId 用户编号 | |
| 77 | + * @param ids 购物项的编号 | |
| 78 | + * @return 购物车列表 | |
| 79 | + */ | |
| 80 | + List<TradeCartDO> getCartList(Long userId, Set<Long> ids); | |
| 81 | + | |
| 82 | + /** | |
| 71 | 83 | * 获得用户的购物车商品 SPU 数量的 Map |
| 72 | 84 | * |
| 73 | 85 | * @param userId 用户编号 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java
| ... | ... | @@ -17,10 +17,7 @@ import org.springframework.transaction.annotation.Transactional; |
| 17 | 17 | import org.springframework.validation.annotation.Validated; |
| 18 | 18 | |
| 19 | 19 | import javax.annotation.Resource; |
| 20 | -import java.util.Collection; | |
| 21 | -import java.util.Comparator; | |
| 22 | -import java.util.List; | |
| 23 | -import java.util.Map; | |
| 20 | +import java.util.*; | |
| 24 | 21 | |
| 25 | 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 26 | 23 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| ... | ... | @@ -166,6 +163,14 @@ public class TradeCartServiceImpl implements TradeCartService { |
| 166 | 163 | return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); |
| 167 | 164 | } |
| 168 | 165 | |
| 166 | + @Override | |
| 167 | + public List<TradeCartDO> getCartList(Long userId, Set<Long> ids) { | |
| 168 | + if (CollUtil.isEmpty(ids)) { | |
| 169 | + return Collections.emptyList(); | |
| 170 | + } | |
| 171 | + return cartMapper.selectListByUserId(userId, ids); | |
| 172 | + } | |
| 173 | + | |
| 169 | 174 | private void deleteCartIfSpuDeleted(List<TradeCartDO> carts, List<ProductSpuRespDTO> spus) { |
| 170 | 175 | // 如果 SPU 被删除,则删除购物车对应的商品。延迟删除 |
| 171 | 176 | carts.removeIf(cart -> { | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
| ... | ... | @@ -34,6 +34,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageRe |
| 34 | 34 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; |
| 35 | 35 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; |
| 36 | 36 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; |
| 37 | +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; | |
| 37 | 38 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 38 | 39 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 39 | 40 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; |
| ... | ... | @@ -41,6 +42,10 @@ import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; |
| 41 | 42 | import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; |
| 42 | 43 | import cn.iocoder.yudao.module.trade.enums.order.*; |
| 43 | 44 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 45 | +import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; | |
| 46 | +import cn.iocoder.yudao.module.trade.service.price.TradePriceService; | |
| 47 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | |
| 48 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | |
| 44 | 49 | import lombok.extern.slf4j.Slf4j; |
| 45 | 50 | import org.springframework.stereotype.Service; |
| 46 | 51 | import org.springframework.transaction.annotation.Transactional; |
| ... | ... | @@ -50,8 +55,7 @@ import java.time.LocalDateTime; |
| 50 | 55 | import java.util.*; |
| 51 | 56 | |
| 52 | 57 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 53 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 54 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | |
| 58 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | |
| 55 | 59 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; |
| 56 | 60 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; |
| 57 | 61 | |
| ... | ... | @@ -71,6 +75,11 @@ public class TradeOrderServiceImpl implements TradeOrderService { |
| 71 | 75 | private TradeOrderItemMapper tradeOrderItemMapper; |
| 72 | 76 | |
| 73 | 77 | @Resource |
| 78 | + private TradeCartService tradeCartService; | |
| 79 | + @Resource | |
| 80 | + private TradePriceService tradePriceService; | |
| 81 | + | |
| 82 | + @Resource | |
| 74 | 83 | private PriceApi priceApi; |
| 75 | 84 | @Resource |
| 76 | 85 | private ProductSkuApi productSkuApi; |
| ... | ... | @@ -92,7 +101,48 @@ public class TradeOrderServiceImpl implements TradeOrderService { |
| 92 | 101 | |
| 93 | 102 | @Override |
| 94 | 103 | public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { |
| 95 | - return null; | |
| 104 | + // 1. 获得收货地址 | |
| 105 | + AddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId()); | |
| 106 | + if (address != null) { | |
| 107 | + settlementReqVO.setAddressId(address.getId()); | |
| 108 | + } | |
| 109 | + | |
| 110 | + // 2. 计算价格 | |
| 111 | + TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, settlementReqVO); | |
| 112 | + | |
| 113 | + // 3. 拼接返回 | |
| 114 | + return TradeOrderConvert.INSTANCE.convert(calculateRespBO, address); | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * 获得用户地址 | |
| 119 | + * | |
| 120 | + * @param userId 用户编号 | |
| 121 | + * @param addressId 地址编号 | |
| 122 | + * @return 地址 | |
| 123 | + */ | |
| 124 | + private AddressRespDTO getAddress(Long userId, Long addressId) { | |
| 125 | + if (addressId != null) { | |
| 126 | + return addressApi.getAddress(addressId, userId); | |
| 127 | + } | |
| 128 | + return addressApi.getDefaultAddress(userId); | |
| 129 | + } | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * 计算订单价格 | |
| 133 | + * | |
| 134 | + * @param userId 用户编号 | |
| 135 | + * @param settlementReqVO 结算信息 | |
| 136 | + * @return 订单价格 | |
| 137 | + */ | |
| 138 | + private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { | |
| 139 | + // 1. 如果来自购物车,则获得购物车的商品 | |
| 140 | + List<TradeCartDO> cartList = tradeCartService.getCartList(userId, | |
| 141 | + convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId)); | |
| 142 | + | |
| 143 | + // 2. 计算价格 | |
| 144 | + TradePriceCalculateReqBO calculateReqBO = TradeOrderConvert.INSTANCE.convert(userId, settlementReqVO, cartList); | |
| 145 | + return tradePriceService.calculatePrice(calculateReqBO); | |
| 96 | 146 | } |
| 97 | 147 | |
| 98 | 148 | @Override |
| ... | ... | @@ -120,29 +170,6 @@ public class TradeOrderServiceImpl implements TradeOrderService { |
| 120 | 170 | return tradeOrderDO.getId(); |
| 121 | 171 | } |
| 122 | 172 | |
| 123 | -// /** | |
| 124 | -// * 校验商品 SKU 是否可出售 | |
| 125 | -// * | |
| 126 | -// * @param items 商品 SKU | |
| 127 | -// * @return 商品 SKU 数组 | |
| 128 | -// */ | |
| 129 | -// private List<ProductSkuRespDTO> validateSkuSaleable(List<Item> items) { | |
| 130 | -// List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); | |
| 131 | -// // SKU 不存在 | |
| 132 | -// if (items.size() != skus.size()) { | |
| 133 | -// throw exception(ORDER_CREATE_SKU_NOT_FOUND); | |
| 134 | -// } | |
| 135 | -// // 校验库存不足 | |
| 136 | -// Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); | |
| 137 | -// items.forEach(item -> { | |
| 138 | -// ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); | |
| 139 | -// if (item.getCount() > sku.getStock()) { | |
| 140 | -// throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); | |
| 141 | -// } | |
| 142 | -// }); | |
| 143 | -// return skus; | |
| 144 | -// } | |
| 145 | - | |
| 146 | 173 | /** |
| 147 | 174 | * 校验商品 SPU 是否可出售 |
| 148 | 175 | * | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceService.java
| ... | ... | @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.price; |
| 3 | 3 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 4 | 4 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 5 | 5 | |
| 6 | +import javax.validation.Valid; | |
| 7 | + | |
| 6 | 8 | /** |
| 7 | 9 | * 价格计算 Service 接口 |
| 8 | 10 | * |
| ... | ... | @@ -16,6 +18,6 @@ public interface TradePriceService { |
| 16 | 18 | * @param calculateReqDTO 计算信息 |
| 17 | 19 | * @return 计算结果 |
| 18 | 20 | */ |
| 19 | - TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqDTO); | |
| 21 | + TradePriceCalculateRespBO calculatePrice(@Valid TradePriceCalculateReqBO calculateReqDTO); | |
| 20 | 22 | |
| 21 | 23 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java
| ... | ... | @@ -2,12 +2,16 @@ package cn.iocoder.yudao.module.trade.service.price; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 4 | 4 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 5 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | |
| 6 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | |
| 7 | +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | |
| 5 | 8 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 6 | 9 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 7 | 10 | import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; |
| 8 | 11 | import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; |
| 9 | 12 | import lombok.extern.slf4j.Slf4j; |
| 10 | 13 | import org.springframework.stereotype.Service; |
| 14 | +import org.springframework.validation.annotation.Validated; | |
| 11 | 15 | |
| 12 | 16 | import javax.annotation.Resource; |
| 13 | 17 | import java.util.List; |
| ... | ... | @@ -15,8 +19,8 @@ import java.util.Map; |
| 15 | 19 | |
| 16 | 20 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 17 | 21 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| 18 | -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | |
| 19 | -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; | |
| 22 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 23 | +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; | |
| 20 | 24 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; |
| 21 | 25 | |
| 22 | 26 | /** |
| ... | ... | @@ -25,22 +29,28 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_C |
| 25 | 29 | * @author 芋道源码 |
| 26 | 30 | */ |
| 27 | 31 | @Service |
| 32 | +@Validated | |
| 28 | 33 | @Slf4j |
| 29 | 34 | public class TradePriceServiceImpl implements TradePriceService { |
| 30 | 35 | |
| 31 | 36 | @Resource |
| 32 | 37 | private ProductSkuApi productSkuApi; |
| 33 | 38 | @Resource |
| 39 | + private ProductSpuApi productSpuApi; | |
| 40 | + | |
| 41 | + @Resource | |
| 34 | 42 | private List<TradePriceCalculator> priceCalculators; |
| 35 | 43 | |
| 36 | 44 | @Override |
| 37 | 45 | public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) { |
| 38 | - // 1. 获得商品 SKU 数组 | |
| 39 | - List<ProductSkuRespDTO> skuList = checkSkus(calculateReqBO); | |
| 46 | + // 1.1 获得商品 SKU 数组 | |
| 47 | + List<ProductSkuRespDTO> skuList = checkSkuList(calculateReqBO); | |
| 48 | + // 1.2 获得商品 SPU 数组 | |
| 49 | + List<ProductSpuRespDTO> spuList = checkSpuList(skuList); | |
| 40 | 50 | |
| 41 | 51 | // 2.1 计算价格 |
| 42 | 52 | TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper |
| 43 | - .buildCalculateResp(calculateReqBO, skuList); | |
| 53 | + .buildCalculateResp(calculateReqBO, spuList, skuList); | |
| 44 | 54 | priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); |
| 45 | 55 | // 2.2 如果最终支付金额小于等于 0,则抛出业务异常 |
| 46 | 56 | if (calculateRespBO.getPrice().getPayPrice() <= 0) { |
| ... | ... | @@ -51,7 +61,7 @@ public class TradePriceServiceImpl implements TradePriceService { |
| 51 | 61 | return calculateRespBO; |
| 52 | 62 | } |
| 53 | 63 | |
| 54 | - private List<ProductSkuRespDTO> checkSkus(TradePriceCalculateReqBO reqBO) { | |
| 64 | + private List<ProductSkuRespDTO> checkSkuList(TradePriceCalculateReqBO reqBO) { | |
| 55 | 65 | // 获得商品 SKU 数组 |
| 56 | 66 | Map<Long, Integer> skuIdCountMap = convertMap(reqBO.getItems(), |
| 57 | 67 | TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount); |
| ... | ... | @@ -70,4 +80,20 @@ public class TradePriceServiceImpl implements TradePriceService { |
| 70 | 80 | return skus; |
| 71 | 81 | } |
| 72 | 82 | |
| 83 | + private List<ProductSpuRespDTO> checkSpuList(List<ProductSkuRespDTO> skuList) { | |
| 84 | + // 获得商品 SPU 数组 | |
| 85 | + List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId)); | |
| 86 | + | |
| 87 | + // 校验商品 SPU | |
| 88 | + spus.forEach(spu -> { | |
| 89 | + if (spu == null) { | |
| 90 | + throw exception(SPU_NOT_EXISTS); | |
| 91 | + } | |
| 92 | + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { | |
| 93 | + throw exception(SPU_NOT_ENABLE); | |
| 94 | + } | |
| 95 | + }); | |
| 96 | + return spus; | |
| 97 | + } | |
| 98 | + | |
| 73 | 99 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.price.bo; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | |
| 3 | 4 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; |
| 4 | 5 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; |
| 5 | 6 | import lombok.Data; |
| ... | ... | @@ -23,7 +24,7 @@ public class TradePriceCalculateRespBO { |
| 23 | 24 | * |
| 24 | 25 | * 枚举 {@link TradeOrderTypeEnum} |
| 25 | 26 | */ |
| 26 | - private Integer orderType; | |
| 27 | + private Integer type; | |
| 27 | 28 | |
| 28 | 29 | /** |
| 29 | 30 | * 订单价格 |
| ... | ... | @@ -163,7 +164,26 @@ public class TradePriceCalculateRespBO { |
| 163 | 164 | */ |
| 164 | 165 | private Integer payPrice; |
| 165 | 166 | |
| 166 | - // TODO 芋艿:这里补充下基本信息,简单一点。 | |
| 167 | + // ========== 商品信息 ========== | |
| 168 | + /** | |
| 169 | + * 商品名 | |
| 170 | + */ | |
| 171 | + private String spuName; | |
| 172 | + /** | |
| 173 | + * 商品图片 | |
| 174 | + * | |
| 175 | + * 优先级:SKU.picUrl > SPU.picUrl | |
| 176 | + */ | |
| 177 | + private String picUrl; | |
| 178 | + /** | |
| 179 | + * 分类编号 | |
| 180 | + */ | |
| 181 | + private Long categoryId; | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * 商品属性数组 | |
| 185 | + */ | |
| 186 | + private List<ProductPropertyValueDetailRespDTO> properties; | |
| 167 | 187 | |
| 168 | 188 | } |
| 169 | 189 | |
| ... | ... | @@ -190,12 +210,6 @@ public class TradePriceCalculateRespBO { |
| 190 | 210 | */ |
| 191 | 211 | private Integer type; |
| 192 | 212 | /** |
| 193 | - * 营销级别 | |
| 194 | - * | |
| 195 | - * 枚举 {@link PromotionLevelEnum} | |
| 196 | - */ | |
| 197 | - private Integer level; | |
| 198 | - /** | |
| 199 | 213 | * 计算时的原价(总),单位:分 |
| 200 | 214 | */ |
| 201 | 215 | private Integer totalPrice; | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; |
| 3 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 6 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | |
| 6 | 7 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 7 | 8 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 8 | 9 | |
| ... | ... | @@ -14,6 +15,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. |
| 14 | 15 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; |
| 15 | 16 | import static java.util.Collections.singletonList; |
| 16 | 17 | |
| 18 | +// TODO 芋艿:改成父类 | |
| 19 | + | |
| 17 | 20 | /** |
| 18 | 21 | * {@link TradePriceCalculator} 的工具类 |
| 19 | 22 | * |
| ... | ... | @@ -24,25 +27,42 @@ import static java.util.Collections.singletonList; |
| 24 | 27 | public class TradePriceCalculatorHelper { |
| 25 | 28 | |
| 26 | 29 | public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, |
| 27 | - List<ProductSkuRespDTO> skuList) { | |
| 30 | + List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) { | |
| 28 | 31 | // 创建 PriceCalculateRespDTO 对象 |
| 29 | 32 | TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); |
| 30 | - result.setOrderType(param.getOrderType()); | |
| 33 | + result.setType(param.getType()); | |
| 34 | + result.setPromotions(new ArrayList<>()); | |
| 35 | + | |
| 31 | 36 | // 创建它的 OrderItem 属性 |
| 32 | - Map<Long, TradePriceCalculateReqBO.Item> skuItemMap = convertMap(param.getItems(), | |
| 33 | - TradePriceCalculateReqBO.Item::getSkuId); | |
| 34 | - result.setItems(new ArrayList<>(skuItemMap.size())); | |
| 35 | - skuList.forEach(sku -> { | |
| 36 | - TradePriceCalculateReqBO.Item skuItem = skuItemMap.get(sku.getId()); | |
| 37 | - TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem() | |
| 38 | - // SKU 字段 | |
| 39 | - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()) | |
| 40 | - .setCount(skuItem.getCount()).setCartId(skuItem.getCartId()).setSelected(skuItem.getSelected()) | |
| 41 | - // 价格字段 | |
| 42 | - .setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * skuItem.getCount()) | |
| 43 | - .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); | |
| 37 | + result.setItems(new ArrayList<>(param.getItems().size())); | |
| 38 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | |
| 39 | + Map<Long, ProductSkuRespDTO> skuMap = convertMap(skuList, ProductSkuRespDTO::getId); | |
| 40 | + param.getItems().forEach(item -> { | |
| 41 | + ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); | |
| 42 | + if (sku == null) { | |
| 43 | + return; | |
| 44 | + } | |
| 45 | + ProductSpuRespDTO spu = spuMap.get(sku.getSpuId()); | |
| 46 | + if (spu == null) { | |
| 47 | + return; | |
| 48 | + } | |
| 49 | + // 商品项 | |
| 50 | + TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem(); | |
| 44 | 51 | result.getItems().add(orderItem); |
| 52 | + orderItem.setSpuId(sku.getSpuId()).setSkuId(sku.getId()) | |
| 53 | + .setCount(item.getCount()).setCartId(item.getCartId()).setSelected(item.getSelected()); | |
| 54 | + // sku 价格 | |
| 55 | + orderItem.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * item.getCount()) | |
| 56 | + .setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); | |
| 57 | + // sku 信息 | |
| 58 | + orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties()); | |
| 59 | + // spu 信息 | |
| 60 | + orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId()); | |
| 61 | + if (orderItem.getPicUrl() == null) { | |
| 62 | + orderItem.setPicUrl(spu.getPicUrl()); | |
| 63 | + } | |
| 45 | 64 | }); |
| 65 | + | |
| 46 | 66 | // 创建它的 Price 属性 |
| 47 | 67 | result.setPrice(new TradePriceCalculateRespBO.Price()); |
| 48 | 68 | recountAllPrice(result); | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java
| ... | ... | @@ -69,7 +69,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest { |
| 69 | 69 | .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); |
| 70 | 70 | // mock 方法(交易订单项) |
| 71 | 71 | TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { |
| 72 | - o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); | |
| 72 | + o.setOrderId(111L).setUserId(userId).setPayPrice(200); | |
| 73 | 73 | o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); |
| 74 | 74 | }); |
| 75 | 75 | when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java
| ... | ... | @@ -25,4 +25,9 @@ public class AddressApiImpl implements AddressApi { |
| 25 | 25 | return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | + @Override | |
| 29 | + public AddressRespDTO getDefaultAddress(Long userId) { | |
| 30 | + return AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId)); | |
| 31 | + } | |
| 32 | + | |
| 28 | 33 | } | ... | ... |