mall + trade:获得订单结算信息,接入支付接口

This commit is contained in:
YunaiV 2023-06-03 00:46:56 +08:00
parent 5de8fa2e42
commit 2a9a869e01
21 changed files with 292 additions and 180 deletions

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.product.api.sku.dto; package cn.iocoder.yudao.module.product.api.sku.dto;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -25,7 +26,7 @@ public class ProductSkuRespDTO {
/** /**
* 属性数组 * 属性数组
*/ */
private List<Property> properties; private List<ProductPropertyValueDetailRespDTO> properties;
/** /**
* 销售价格单位 * 销售价格单位
*/ */
@ -63,30 +64,4 @@ public class ProductSkuRespDTO {
*/ */
private Double volume; private Double volume;
/**
* 商品属性
*/
@Data
public static class Property {
/**
* 属性编号
*/
private Long propertyId;
/**
* 属性名字
*/
private String propertyName;
/**
* 属性值编号
*/
private Long valueId;
/**
* 属性值名字
*/
private String valueName;
}
} }

View File

@ -18,6 +18,9 @@ public class AppProductSpuDetailRespVO {
@Schema(description = "商品名称", required = true, example = "芋道") @Schema(description = "商品名称", required = true, example = "芋道")
private String name; private String name;
@Schema(description = "商品简介", required = true, example = "我是一个快乐简介")
private String introduction;
@Schema(description = "商品详情", required = true, example = "我是商品描述") @Schema(description = "商品详情", required = true, example = "我是商品描述")
private String description; private String description;

View File

@ -93,7 +93,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
assertNull(promotion.getId()); assertNull(promotion.getId());
assertEquals(promotion.getName(), "会员折扣"); assertEquals(promotion.getName(), "会员折扣");
assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType());
assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel());
assertEquals(promotion.getTotalPrice(), 200); assertEquals(promotion.getTotalPrice(), 200);
assertEquals(promotion.getDiscountPrice(), 20); assertEquals(promotion.getDiscountPrice(), 20);
assertTrue(promotion.getMatch()); assertTrue(promotion.getMatch());
@ -264,7 +263,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getId(), 1000L);
assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getName(), "活动 1000 号");
assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType());
assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel());
assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getTotalPrice(), 350);
assertEquals(promotion01.getDiscountPrice(), 70); assertEquals(promotion01.getDiscountPrice(), 70);
assertTrue(promotion01.getMatch()); assertTrue(promotion01.getMatch());
@ -283,7 +281,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
assertEquals(promotion02.getId(), 2000L); assertEquals(promotion02.getId(), 2000L);
assertEquals(promotion02.getName(), "活动 2000 号"); assertEquals(promotion02.getName(), "活动 2000 号");
assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType());
assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel());
assertEquals(promotion02.getTotalPrice(), 120); assertEquals(promotion02.getTotalPrice(), 120);
assertEquals(promotion02.getDiscountPrice(), 60); assertEquals(promotion02.getDiscountPrice(), 60);
assertTrue(promotion02.getMatch()); assertTrue(promotion02.getMatch());
@ -352,7 +349,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
assertEquals(promotion01.getId(), 1000L); assertEquals(promotion01.getId(), 1000L);
assertEquals(promotion01.getName(), "活动 1000 号"); assertEquals(promotion01.getName(), "活动 1000 号");
assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType());
assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel());
assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getTotalPrice(), 350);
assertEquals(promotion01.getDiscountPrice(), 0); assertEquals(promotion01.getDiscountPrice(), 0);
assertFalse(promotion01.getMatch()); assertFalse(promotion01.getMatch());
@ -434,7 +430,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
assertEquals(promotion01.getId(), 1024L); assertEquals(promotion01.getId(), 1024L);
assertEquals(promotion01.getName(), "程序员节"); assertEquals(promotion01.getName(), "程序员节");
assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType());
assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel());
assertEquals(promotion01.getTotalPrice(), 350); assertEquals(promotion01.getTotalPrice(), 350);
assertEquals(promotion01.getDiscountPrice(), 70); assertEquals(promotion01.getDiscountPrice(), 70);
assertTrue(promotion01.getMatch()); assertTrue(promotion01.getMatch());

View File

@ -1,5 +1,10 @@
### /trade-order/settlement 获得订单结算信息 ### /trade-order/settlement 获得订单结算信息(基于商品)
GET {{appApi}}/trade/order/settlement?cartIds=1 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
Authorization: Bearer {{appToken}}
tenant-id: {{appTenentId}}
### /trade-order/settlement 获得订单结算信息(基于购物车)
GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1
Authorization: Bearer {{appToken}} Authorization: Bearer {{appToken}}
tenant-id: {{appTenentId}} tenant-id: {{appTenentId}}

View File

@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -53,78 +51,8 @@ public class AppTradeOrderController {
@GetMapping("/settlement") @GetMapping("/settlement")
@Operation(summary = "获得订单结算信息") @Operation(summary = "获得订单结算信息")
@PreAuthenticated @PreAuthenticated
public CommonResult<AppTradeOrderSettlementRespVO> settlementOrder( public CommonResult<AppTradeOrderSettlementRespVO> settlementOrder(@Valid AppTradeOrderSettlementReqVO settlementReqVO) {
@Valid AppTradeOrderSettlementReqVO settlementReqVO) { return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO));
if (true) {
return success(tradeOrderService.settlementOrder(getLoginUserId(), settlementReqVO));
}
// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId));
AppTradeOrderSettlementRespVO settlement = new AppTradeOrderSettlementRespVO();
AppTradeOrderSettlementRespVO.Price price = new AppTradeOrderSettlementRespVO.Price();
price.setTotalPrice(1000);
price.setDeliveryPrice(200);
price.setCouponPrice(100);
price.setPointPrice(50);
price.setPayPrice(950);
List<AppTradeOrderSettlementRespVO.Item> skus = new ArrayList<>();
AppTradeOrderSettlementRespVO.Item item1 = new AppTradeOrderSettlementRespVO.Item();
item1.setCartId(1L);
item1.setSpuId(2048L);
item1.setSpuName("Apple iPhone 12");
item1.setSkuId(1024);
item1.setPrice(500);
item1.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg");
item1.setCount(2);
List<AppProductPropertyValueDetailRespVO> properties1 = new ArrayList<>();
AppProductPropertyValueDetailRespVO property1 = new AppProductPropertyValueDetailRespVO();
property1.setPropertyId(1L);
property1.setPropertyName("尺寸");
property1.setValueId(2L);
property1.setValueName("");
properties1.add(property1);
item1.setProperties(properties1);
AppTradeOrderSettlementRespVO.Item item2 = new AppTradeOrderSettlementRespVO.Item();
item2.setCartId(2L);
item2.setSpuId(3072L);
item2.setSpuName("Samsung Galaxy S21");
item2.setSkuId(2048);
item2.setPrice(800);
item2.setPicUrl("https://pro.crmeb.net/uploads/attach/2022/10/12/0c56f9abb80d2775fc1e80dbe4f8826a.jpg");
item2.setCount(1);
List<AppProductPropertyValueDetailRespVO> properties2 = new ArrayList<>();
AppProductPropertyValueDetailRespVO property2 = new AppProductPropertyValueDetailRespVO();
property2.setPropertyId(10L);
property2.setPropertyName("颜色");
property2.setValueId(20L);
property2.setValueName("白色");
properties2.add(property2);
item2.setProperties(properties2);
skus.add(item1);
skus.add(item2);
settlement.setItems(skus);
settlement.setPrice(price);
AppTradeOrderSettlementRespVO.Address address = new AppTradeOrderSettlementRespVO.Address();
address.setId(1L);
address.setName("John");
address.setMobile("18888888888");
address.setProvinceId(1L);
address.setProvinceName("Beijing");
address.setCityId(1L);
address.setCityName("Beijing");
address.setDistrictId(1L);
address.setDistrictName("Chaoyang Distripct");
address.setDetailAddress("No. 10, Xinzhong Street, Chaoyang District");
address.setDefaulted(true);
settlement.setAddress(address);
return success(settlement);
} }
@PostMapping("/create") @PostMapping("/create")

View File

@ -1,23 +1,60 @@
package cn.iocoder.yudao.module.trade.controller.app.order.vo; package cn.iocoder.yudao.module.trade.controller.app.order.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotEmpty; import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
@Schema(description = "用户 App - 交易订单结算 Request VO") @Schema(description = "用户 App - 交易订单结算 Request VO")
@Data @Data
public class AppTradeOrderSettlementReqVO { public class AppTradeOrderSettlementReqVO {
@NotNull(message = "交易类型不能为空")
@InEnum(value = TradeOrderTypeEnum.class, message = "交易类型必须是 {value}")
private Integer type;
@Schema(description = "商品项数组", required = true)
@NotNull(message = "商品不能为空")
private List<Item> items;
@Schema(description = "收件地址编号", example = "1") @Schema(description = "收件地址编号", example = "1")
private Long addressId; private Long addressId;
@Schema(description = "优惠劵编号", example = "1024") @Schema(description = "优惠劵编号", example = "1024")
private Long couponId; private Long couponId;
@Schema(description = "购物车项的编号数组", required = true, example = "true") @Data
@NotEmpty(message = "购物车项不能为空") @Schema(description = "用户 App - 商品项")
private List<Long> cartIds; @Valid
public static class Item {
@Schema(description = "商品 SKU 编号", example = "2048")
private Long skuId;
@Schema(description = "购买数量", example = "1")
@Min(value = 1, message = "购买数量最小值为 {value}")
private Integer count;
@Schema(description = "购物车项的编号", example = "1024")
private Long cartId;
@AssertTrue(message = "商品不正确")
@JsonIgnore
public boolean isValid() {
// 组合一skuId + count 使用商品 SKU
if (skuId != null && count != null) {
return true;
}
// 组合二cartId 使用购物车项
return cartId != null;
}
}
} }

View File

@ -91,17 +91,17 @@ public class AppTradeOrderSettlementRespVO {
private String mobile; private String mobile;
@Schema(description = "省份编号", required = true, example = "1") @Schema(description = "省份编号", required = true, example = "1")
private Long provinceId; private Integer provinceId;
@Schema(description = "省份名字", required = true, example = "北京") @Schema(description = "省份名字", required = true, example = "北京")
private String provinceName; private String provinceName;
@Schema(description = "城市编号", required = true, example = "1") @Schema(description = "城市编号", required = true, example = "1")
private Long cityId; private Integer cityId;
@Schema(description = "城市名字", required = true, example = "北京") @Schema(description = "城市名字", required = true, example = "北京")
private String cityName; private String cityName;
@Schema(description = "地区编号", required = true, example = "1") @Schema(description = "地区编号", required = true, example = "1")
private Long districtId; private Integer districtId;
@Schema(description = "地区名字", required = true, example = "朝阳区") @Schema(description = "地区名字", required = true, example = "朝阳区")
private String districtName; private String districtName;

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.convert.order;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 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
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.Mappings; import org.mapstruct.Mappings;
@ -241,4 +243,45 @@ public interface TradeOrderConvert {
AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
List<TradeCartDO> cartList) {
TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO();
reqBO.setUserId(userId).setType(settlementReqVO.getType())
.setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId())
.setItems(new ArrayList<>(settlementReqVO.getItems().size()));
// 商品项的构建
Map<Long, TradeCartDO> cartMap = convertMap(cartList, TradeCartDO::getId);
for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) {
// 情况一skuId + count
if (item.getSkuId() != null) {
reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(item.getSkuId()).setCount(item.getCount())
.setSelected(true)); // true 的原因下单一定选中
continue;
}
// 情况二cartId
TradeCartDO cart = cartMap.get(item.getCartId());
if (cart == null) {
continue;
}
reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(cart.getSkuId()).setCount(cart.getCount())
.setCartId(item.getCartId()).setSelected(true)); // true 的原因下单一定选中
}
return reqBO;
}
default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, AddressRespDTO address) {
AppTradeOrderSettlementRespVO respVO = convert0(calculate, address);
if (address != null) {
Area area = AreaUtils.getArea(address.getAreaId());
respVO.getAddress().setDistrictId(area.getId());
respVO.getAddress().setDistrictName(area.getName());
respVO.getAddress().setCityId(area.getParent().getId());
respVO.getAddress().setCityName(area.getParent().getName());
respVO.getAddress().setProvinceId(area.getParent().getParent().getId());
respVO.getAddress().setProvinceName(area.getParent().getParent().getName());
}
return respVO;
}
AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
} }

View File

@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
@Mapper @Mapper
public interface TradeCartMapper extends BaseMapperX<TradeCartDO> { public interface TradeCartMapper extends BaseMapperX<TradeCartDO> {
@ -70,4 +71,10 @@ public interface TradeCartMapper extends BaseMapperX<TradeCartDO> {
update(updateObject, new LambdaQueryWrapper<TradeCartDO>().in(TradeCartDO::getId, ids)); update(updateObject, new LambdaQueryWrapper<TradeCartDO>().in(TradeCartDO::getId, ids));
} }
default List<TradeCartDO> selectListByUserId(Long userId, Set<Long> ids) {
return selectList(new LambdaQueryWrapper<TradeCartDO>()
.eq(TradeCartDO::getUserId, userId)
.in(TradeCartDO::getId, ids));
}
} }

View File

@ -4,10 +4,13 @@ import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO;
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartResetReqVO;
import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* 购物车 Service 接口 * 购物车 Service 接口
@ -67,6 +70,15 @@ public interface TradeCartService {
*/ */
AppTradeCartListRespVO getCartList(Long userId); AppTradeCartListRespVO getCartList(Long userId);
/**
* 查询用户的购物车列表
*
* @param userId 用户编号
* @param ids 购物项的编号
* @return 购物车列表
*/
List<TradeCartDO> getCartList(Long userId, Set<Long> ids);
/** /**
* 获得用户的购物车商品 SPU 数量的 Map * 获得用户的购物车商品 SPU 数量的 Map
* *

View File

@ -17,10 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection; import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -166,6 +163,14 @@ public class TradeCartServiceImpl implements TradeCartService {
return TradeCartConvert.INSTANCE.convertList(carts, spus, skus); return TradeCartConvert.INSTANCE.convertList(carts, spus, skus);
} }
@Override
public List<TradeCartDO> getCartList(Long userId, Set<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return cartMapper.selectListByUserId(userId, ids);
}
private void deleteCartIfSpuDeleted(List<TradeCartDO> carts, List<ProductSpuRespDTO> spus) { private void deleteCartIfSpuDeleted(List<TradeCartDO> carts, List<ProductSpuRespDTO> spus) {
// 如果 SPU 被删除则删除购物车对应的商品延迟删除 // 如果 SPU 被删除则删除购物车对应的商品延迟删除
carts.removeIf(cart -> { carts.removeIf(cart -> {

View File

@ -34,6 +34,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageRe
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
@ -41,6 +42,10 @@ import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.enums.order.*;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -50,8 +55,7 @@ import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
@ -70,6 +74,11 @@ public class TradeOrderServiceImpl implements TradeOrderService {
@Resource @Resource
private TradeOrderItemMapper tradeOrderItemMapper; private TradeOrderItemMapper tradeOrderItemMapper;
@Resource
private TradeCartService tradeCartService;
@Resource
private TradePriceService tradePriceService;
@Resource @Resource
private PriceApi priceApi; private PriceApi priceApi;
@Resource @Resource
@ -92,7 +101,48 @@ public class TradeOrderServiceImpl implements TradeOrderService {
@Override @Override
public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) {
return null; // 1. 获得收货地址
AddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId());
if (address != null) {
settlementReqVO.setAddressId(address.getId());
}
// 2. 计算价格
TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, settlementReqVO);
// 3. 拼接返回
return TradeOrderConvert.INSTANCE.convert(calculateRespBO, address);
}
/**
* 获得用户地址
*
* @param userId 用户编号
* @param addressId 地址编号
* @return 地址
*/
private AddressRespDTO getAddress(Long userId, Long addressId) {
if (addressId != null) {
return addressApi.getAddress(addressId, userId);
}
return addressApi.getDefaultAddress(userId);
}
/**
* 计算订单价格
*
* @param userId 用户编号
* @param settlementReqVO 结算信息
* @return 订单价格
*/
private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) {
// 1. 如果来自购物车则获得购物车的商品
List<TradeCartDO> cartList = tradeCartService.getCartList(userId,
convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId));
// 2. 计算价格
TradePriceCalculateReqBO calculateReqBO = TradeOrderConvert.INSTANCE.convert(userId, settlementReqVO, cartList);
return tradePriceService.calculatePrice(calculateReqBO);
} }
@Override @Override
@ -120,29 +170,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
return tradeOrderDO.getId(); return tradeOrderDO.getId();
} }
// /**
// * 校验商品 SKU 是否可出售
// *
// * @param items 商品 SKU
// * @return 商品 SKU 数组
// */
// private List<ProductSkuRespDTO> validateSkuSaleable(List<Item> items) {
// List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId));
// // SKU 不存在
// if (items.size() != skus.size()) {
// throw exception(ORDER_CREATE_SKU_NOT_FOUND);
// }
// // 校验库存不足
// Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId);
// items.forEach(item -> {
// ProductSkuRespDTO sku = skuMap.get(item.getSkuId());
// if (item.getCount() > sku.getStock()) {
// throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH);
// }
// });
// return skus;
// }
/** /**
* 校验商品 SPU 是否可出售 * 校验商品 SPU 是否可出售
* *

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.price;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import javax.validation.Valid;
/** /**
* 价格计算 Service 接口 * 价格计算 Service 接口
* *
@ -16,6 +18,6 @@ public interface TradePriceService {
* @param calculateReqDTO 计算信息 * @param calculateReqDTO 计算信息
* @return 计算结果 * @return 计算结果
*/ */
TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqDTO); TradePriceCalculateRespBO calculatePrice(@Valid TradePriceCalculateReqBO calculateReqDTO);
} }

View File

@ -2,12 +2,16 @@ package cn.iocoder.yudao.module.trade.service.price;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator;
import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
@ -15,8 +19,8 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
/** /**
@ -25,22 +29,28 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_C
* @author 芋道源码 * @author 芋道源码
*/ */
@Service @Service
@Validated
@Slf4j @Slf4j
public class TradePriceServiceImpl implements TradePriceService { public class TradePriceServiceImpl implements TradePriceService {
@Resource @Resource
private ProductSkuApi productSkuApi; private ProductSkuApi productSkuApi;
@Resource
private ProductSpuApi productSpuApi;
@Resource @Resource
private List<TradePriceCalculator> priceCalculators; private List<TradePriceCalculator> priceCalculators;
@Override @Override
public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) { public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) {
// 1. 获得商品 SKU 数组 // 1.1 获得商品 SKU 数组
List<ProductSkuRespDTO> skuList = checkSkus(calculateReqBO); List<ProductSkuRespDTO> skuList = checkSkuList(calculateReqBO);
// 1.2 获得商品 SPU 数组
List<ProductSpuRespDTO> spuList = checkSpuList(skuList);
// 2.1 计算价格 // 2.1 计算价格
TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper TradePriceCalculateRespBO calculateRespBO = TradePriceCalculatorHelper
.buildCalculateResp(calculateReqBO, skuList); .buildCalculateResp(calculateReqBO, spuList, skuList);
priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO)); priceCalculators.forEach(calculator -> calculator.calculate(calculateReqBO, calculateRespBO));
// 2.2 如果最终支付金额小于等于 0则抛出业务异常 // 2.2 如果最终支付金额小于等于 0则抛出业务异常
if (calculateRespBO.getPrice().getPayPrice() <= 0) { if (calculateRespBO.getPrice().getPayPrice() <= 0) {
@ -51,7 +61,7 @@ public class TradePriceServiceImpl implements TradePriceService {
return calculateRespBO; return calculateRespBO;
} }
private List<ProductSkuRespDTO> checkSkus(TradePriceCalculateReqBO reqBO) { private List<ProductSkuRespDTO> checkSkuList(TradePriceCalculateReqBO reqBO) {
// 获得商品 SKU 数组 // 获得商品 SKU 数组
Map<Long, Integer> skuIdCountMap = convertMap(reqBO.getItems(), Map<Long, Integer> skuIdCountMap = convertMap(reqBO.getItems(),
TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount); TradePriceCalculateReqBO.Item::getSkuId, TradePriceCalculateReqBO.Item::getCount);
@ -70,4 +80,20 @@ public class TradePriceServiceImpl implements TradePriceService {
return skus; return skus;
} }
private List<ProductSpuRespDTO> checkSpuList(List<ProductSkuRespDTO> skuList) {
// 获得商品 SPU 数组
List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId));
// 校验商品 SPU
spus.forEach(spu -> {
if (spu == null) {
throw exception(SPU_NOT_EXISTS);
}
if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
throw exception(SPU_NOT_ENABLE);
}
});
return spus;
}
} }

View File

@ -21,7 +21,7 @@ public class TradePriceCalculateReqBO {
* *
* 枚举 {@link TradeOrderTypeEnum} * 枚举 {@link TradeOrderTypeEnum}
*/ */
private Integer orderType; private Integer type;
/** /**
* 用户编号 * 用户编号

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.trade.service.price.bo; package cn.iocoder.yudao.module.trade.service.price.bo;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
import lombok.Data; import lombok.Data;
@ -23,7 +24,7 @@ public class TradePriceCalculateRespBO {
* *
* 枚举 {@link TradeOrderTypeEnum} * 枚举 {@link TradeOrderTypeEnum}
*/ */
private Integer orderType; private Integer type;
/** /**
* 订单价格 * 订单价格
@ -163,7 +164,26 @@ public class TradePriceCalculateRespBO {
*/ */
private Integer payPrice; private Integer payPrice;
// TODO 芋艿这里补充下基本信息简单一点 // ========== 商品信息 ==========
/**
* 商品名
*/
private String spuName;
/**
* 商品图片
*
* 优先级SKU.picUrl > SPU.picUrl
*/
private String picUrl;
/**
* 分类编号
*/
private Long categoryId;
/**
* 商品属性数组
*/
private List<ProductPropertyValueDetailRespDTO> properties;
} }
@ -189,12 +209,6 @@ public class TradePriceCalculateRespBO {
* 枚举 {@link PromotionTypeEnum} * 枚举 {@link PromotionTypeEnum}
*/ */
private Integer type; private Integer type;
/**
* 营销级别
*
* 枚举 {@link PromotionLevelEnum}
*/
private Integer level;
/** /**
* 计算时的原价单位 * 计算时的原价单位
*/ */

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.price.calculator;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
@ -14,6 +15,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
// TODO 芋艿改成父类
/** /**
* {@link TradePriceCalculator} 的工具类 * {@link TradePriceCalculator} 的工具类
* *
@ -24,25 +27,42 @@ import static java.util.Collections.singletonList;
public class TradePriceCalculatorHelper { public class TradePriceCalculatorHelper {
public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param, public static TradePriceCalculateRespBO buildCalculateResp(TradePriceCalculateReqBO param,
List<ProductSkuRespDTO> skuList) { List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
// 创建 PriceCalculateRespDTO 对象 // 创建 PriceCalculateRespDTO 对象
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
result.setOrderType(param.getOrderType()); result.setType(param.getType());
result.setPromotions(new ArrayList<>());
// 创建它的 OrderItem 属性 // 创建它的 OrderItem 属性
Map<Long, TradePriceCalculateReqBO.Item> skuItemMap = convertMap(param.getItems(), result.setItems(new ArrayList<>(param.getItems().size()));
TradePriceCalculateReqBO.Item::getSkuId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
result.setItems(new ArrayList<>(skuItemMap.size())); Map<Long, ProductSkuRespDTO> skuMap = convertMap(skuList, ProductSkuRespDTO::getId);
skuList.forEach(sku -> { param.getItems().forEach(item -> {
TradePriceCalculateReqBO.Item skuItem = skuItemMap.get(sku.getId()); ProductSkuRespDTO sku = skuMap.get(item.getSkuId());
TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem() if (sku == null) {
// SKU 字段 return;
.setSpuId(sku.getSpuId()).setSkuId(sku.getId()) }
.setCount(skuItem.getCount()).setCartId(skuItem.getCartId()).setSelected(skuItem.getSelected()) ProductSpuRespDTO spu = spuMap.get(sku.getSpuId());
// 价格字段 if (spu == null) {
.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * skuItem.getCount()) return;
.setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0); }
// 商品项
TradePriceCalculateRespBO.OrderItem orderItem = new TradePriceCalculateRespBO.OrderItem();
result.getItems().add(orderItem); result.getItems().add(orderItem);
orderItem.setSpuId(sku.getSpuId()).setSkuId(sku.getId())
.setCount(item.getCount()).setCartId(item.getCartId()).setSelected(item.getSelected());
// sku 价格
orderItem.setPrice(sku.getPrice()).setPayPrice(sku.getPrice() * item.getCount())
.setDiscountPrice(0).setDeliveryPrice(0).setCouponPrice(0).setPointPrice(0);
// sku 信息
orderItem.setPicUrl(sku.getPicUrl()).setProperties(sku.getProperties());
// spu 信息
orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId());
if (orderItem.getPicUrl() == null) {
orderItem.setPicUrl(spu.getPicUrl());
}
}); });
// 创建它的 Price 属性 // 创建它的 Price 属性
result.setPrice(new TradePriceCalculateRespBO.Price()); result.setPrice(new TradePriceCalculateRespBO.Price());
recountAllPrice(result); recountAllPrice(result);

View File

@ -69,7 +69,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
.setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
// mock 方法交易订单项 // mock 方法交易订单项
TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); o.setOrderId(111L).setUserId(userId).setPayPrice(200);
o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
}); });
when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) when(tradeOrderService.getOrderItem(eq(1024L), eq(1L)))

View File

@ -18,4 +18,12 @@ public interface AddressApi {
*/ */
AddressRespDTO getAddress(Long id, Long userId); AddressRespDTO getAddress(Long id, Long userId);
/**
* 获得用户默认收件地址
*
* @param userId 用户编号
* @return 用户收件地址
*/
AddressRespDTO getDefaultAddress(Long userId);
} }

View File

@ -29,7 +29,7 @@ public class AddressRespDTO {
/** /**
* 地区编号 * 地区编号
*/ */
private Long areaId; private Integer areaId;
/** /**
* 邮编 * 邮编
*/ */

View File

@ -25,4 +25,9 @@ public class AddressApiImpl implements AddressApi {
return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id));
} }
@Override
public AddressRespDTO getDefaultAddress(Long userId) {
return AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId));
}
} }