Commit e4a2c738b27e593f26e232bbdee3ca30c052e6ef

Authored by YunaiV
1 parent 36da5d69

订单:

1. 增加查询物流接口
Showing 22 changed files with 338 additions and 266 deletions
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalDateTimeDeserializer.java
1 package cn.iocoder.yudao.framework.jackson.core.databind; 1 package cn.iocoder.yudao.framework.jackson.core.databind;
2 2
3 import com.fasterxml.jackson.core.JsonParser; 3 import com.fasterxml.jackson.core.JsonParser;
4 -import com.fasterxml.jackson.core.JsonProcessingException;  
5 import com.fasterxml.jackson.databind.DeserializationContext; 4 import com.fasterxml.jackson.databind.DeserializationContext;
6 import com.fasterxml.jackson.databind.JsonDeserializer; 5 import com.fasterxml.jackson.databind.JsonDeserializer;
7 6
@@ -20,7 +19,7 @@ public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> { @@ -20,7 +19,7 @@ public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
20 public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer(); 19 public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer();
21 20
22 @Override 21 @Override
23 - public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { 22 + public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
24 return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault()); 23 return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault());
25 } 24 }
26 } 25 }
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/core/databind/LocalTimeJson.java deleted
1 -package cn.iocoder.yudao.framework.jackson.core.databind;  
2 -  
3 -import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;  
4 -import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;  
5 -  
6 -import java.time.ZoneId;  
7 -import java.time.format.DateTimeFormatter;  
8 -  
9 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_HOUR_MINUTE_SECOND;  
10 -  
11 -public class LocalTimeJson {  
12 -  
13 - public static final LocalTimeSerializer SERIALIZER = new LocalTimeSerializer(DateTimeFormatter  
14 - .ofPattern(FORMAT_HOUR_MINUTE_SECOND)  
15 - .withZone(ZoneId.systemDefault()));  
16 -  
17 - public static final LocalTimeDeserializer DESERIALIZABLE = new LocalTimeDeserializer(DateTimeFormatter  
18 - .ofPattern(FORMAT_HOUR_MINUTE_SECOND)  
19 - .withZone(ZoneId.systemDefault()));  
20 -  
21 -}  
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
@@ -35,3 +35,8 @@ tenant-id: {{appTenentId}} @@ -35,3 +35,8 @@ tenant-id: {{appTenentId}}
35 GET {{appApi}}/trade/order/get-detail?id=21 35 GET {{appApi}}/trade/order/get-detail?id=21
36 Authorization: Bearer {{appToken}} 36 Authorization: Bearer {{appToken}}
37 tenant-id: {{appTenentId}} 37 tenant-id: {{appTenentId}}
  38 +
  39 +### 获得交易订单的物流轨迹
  40 +GET {{appApi}}/trade/order/get-express-track-list?id=70
  41 +Authorization: Bearer {{appToken}}
  42 +tenant-id: {{appTenentId}}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
16 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; 16 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
17 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 17 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
18 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; 18 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
  19 +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
19 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; 20 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
20 import com.google.common.collect.Maps; 21 import com.google.common.collect.Maps;
21 import io.swagger.v3.oas.annotations.Operation; 22 import io.swagger.v3.oas.annotations.Operation;
@@ -45,6 +46,8 @@ public class AppTradeOrderController { @@ -45,6 +46,8 @@ public class AppTradeOrderController {
45 @Resource 46 @Resource
46 private TradeOrderService tradeOrderService; 47 private TradeOrderService tradeOrderService;
47 @Resource 48 @Resource
  49 + private TradeOrderQueryService tradeOrderQueryService;
  50 + @Resource
48 private DeliveryExpressService deliveryExpressService; 51 private DeliveryExpressService deliveryExpressService;
49 52
50 @Resource 53 @Resource
@@ -99,6 +102,14 @@ public class AppTradeOrderController { @@ -99,6 +102,14 @@ public class AppTradeOrderController {
99 propertyValueDetails, tradeOrderProperties, express)); 102 propertyValueDetails, tradeOrderProperties, express));
100 } 103 }
101 104
  105 + @GetMapping("/get-express-track-list")
  106 + @Operation(summary = "获得交易订单的物流轨迹")
  107 + @Parameter(name = "id", description = "交易订单编号")
  108 + public CommonResult<List<?>> getOrderExpressTrackList(@RequestParam("id") Long id) {
  109 + return success(TradeOrderConvert.INSTANCE.convertList02(
  110 + tradeOrderQueryService.getExpressTrackList(id, getLoginUserId())));
  111 + }
  112 +
102 @GetMapping("/page") 113 @GetMapping("/page")
103 @Operation(summary = "获得交易订单分页") 114 @Operation(summary = "获得交易订单分页")
104 public CommonResult<PageResult<AppTradeOrderPageItemRespVO>> getOrderPage(AppTradeOrderPageReqVO reqVO) { 115 public CommonResult<PageResult<AppTradeOrderPageItemRespVO>> getOrderPage(AppTradeOrderPageReqVO reqVO) {
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppOrderExpressTrackRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.order.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 快递查询的轨迹 Resp DTO
  10 + *
  11 + * @author jason
  12 + */
  13 +@Schema(description = "用户 App - 快递查询的轨迹 Response VO")
  14 +@Data
  15 +public class AppOrderExpressTrackRespDTO {
  16 +
  17 + @Schema(description = "发生时间", requiredMode = Schema.RequiredMode.REQUIRED)
  18 + private LocalDateTime time;
  19 +
  20 + @Schema(description = "快递状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "已签收")
  21 + private String content;
  22 +
  23 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -29,6 +29,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; @@ -29,6 +29,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
30 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 30 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
31 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; 31 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
  32 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
32 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 33 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
33 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; 34 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
34 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; 35 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
@@ -340,4 +341,6 @@ public interface TradeOrderConvert { @@ -340,4 +341,6 @@ public interface TradeOrderConvert {
340 CombinationRecordCreateReqDTO convert(TradeOrderDO order, TradeOrderItemDO orderItem, 341 CombinationRecordCreateReqDTO convert(TradeOrderDO order, TradeOrderItemDO orderItem,
341 AppTradeOrderCreateReqVO createReqVO, MemberUserRespDTO user); 342 AppTradeOrderCreateReqVO createReqVO, MemberUserRespDTO user);
342 343
  344 + List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list);
  345 +
343 } 346 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/config/TradeExpressProperties.java
@@ -59,7 +59,7 @@ public class TradeExpressProperties { @@ -59,7 +59,7 @@ public class TradeExpressProperties {
59 } 59 }
60 60
61 /** 61 /**
62 - * 快递100 配置项 62 + * 快递 100 配置项
63 */ 63 */
64 @Data 64 @Data
65 public static class Kd100Config { 65 public static class Kd100Config {
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/convert/ExpressQueryConvert.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100.Kd
7 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO; 7 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryReqDTO;
8 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryRespDTO; 8 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao.KdNiaoExpressQueryRespDTO;
9 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
  10 +import org.mapstruct.Mapping;
10 import org.mapstruct.factory.Mappers; 11 import org.mapstruct.factory.Mappers;
11 12
12 import java.util.List; 13 import java.util.List;
@@ -16,9 +17,14 @@ public interface ExpressQueryConvert { @@ -16,9 +17,14 @@ public interface ExpressQueryConvert {
16 17
17 ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class); 18 ExpressQueryConvert INSTANCE = Mappers.getMapper(ExpressQueryConvert.class);
18 19
19 - List<ExpressTrackRespDTO> convertList(List<KdNiaoExpressQueryRespDTO.ExpressTrack> expressTrackList); 20 + List<ExpressTrackRespDTO> convertList(List<KdNiaoExpressQueryRespDTO.ExpressTrack> list);
  21 + @Mapping(source = "acceptTime", target = "time")
  22 + @Mapping(source = "acceptStation", target = "content")
  23 + ExpressTrackRespDTO convert(KdNiaoExpressQueryRespDTO.ExpressTrack track);
20 24
21 - List<ExpressTrackRespDTO> convertList2(List<Kd100ExpressQueryRespDTO.ExpressTrack> expressTrackList); 25 + List<ExpressTrackRespDTO> convertList2(List<Kd100ExpressQueryRespDTO.ExpressTrack> list);
  26 + @Mapping(source = "context", target = "content")
  27 + ExpressTrackRespDTO convert(Kd100ExpressQueryRespDTO.ExpressTrack track);
22 28
23 KdNiaoExpressQueryReqDTO convert(ExpressTrackQueryReqDTO dto); 29 KdNiaoExpressQueryReqDTO convert(ExpressTrackQueryReqDTO dto);
24 30
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/ExpressTrackRespDTO.java
@@ -2,23 +2,24 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto; @@ -2,23 +2,24 @@ package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
  5 +import java.time.LocalDateTime;
  6 +
5 /** 7 /**
6 - * 快递查询 Resp DTO 8 + * 快递查询的轨迹 Resp DTO
7 * 9 *
8 * @author jason 10 * @author jason
9 */ 11 */
10 @Data 12 @Data
11 public class ExpressTrackRespDTO { 13 public class ExpressTrackRespDTO {
12 14
13 - // TODO @jason:LocalDateTime  
14 /** 15 /**
15 * 发生时间 16 * 发生时间
16 */ 17 */
17 - private String time;  
18 - // TODO @jason:其它字段可能要补充下 18 + private LocalDateTime time;
  19 +
19 /** 20 /**
20 * 快递状态 21 * 快递状态
21 */ 22 */
22 - private String state; 23 + private String content;
23 24
24 } 25 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryReqDTO.java
@@ -29,20 +29,5 @@ public class Kd100ExpressQueryReqDTO { @@ -29,20 +29,5 @@ public class Kd100ExpressQueryReqDTO {
29 * 收、寄件人的电话号码 29 * 收、寄件人的电话号码
30 */ 30 */
31 private String phone; 31 private String phone;
32 - /**  
33 - * 出发地城市  
34 - */  
35 - private String from;  
36 - /**  
37 - * 目的地城市,到达目的地后会加大监控频率  
38 - */  
39 - private String to;  
40 -  
41 - /**  
42 - * 返回结果排序  
43 - *  
44 - * desc 降序(默认), asc 升序  
45 - */  
46 - private String order;  
47 32
48 } 33 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kd100/Kd100ExpressQueryRespDTO.java
1 package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100; 1 package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kd100;
2 2
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
3 import com.fasterxml.jackson.annotation.JsonProperty; 4 import com.fasterxml.jackson.annotation.JsonProperty;
4 import lombok.Data; 5 import lombok.Data;
5 6
  7 +import java.time.LocalDateTime;
6 import java.util.List; 8 import java.util.List;
7 9
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
  12 +
8 /** 13 /**
9 - * 快递 100 实时快递查询 Resp DTO 参见 <a href="https://api.kuaidi100.com/document/5f0ffb5ebc8da837cbd8aefc">快递 100 文档</a> 14 + * 快递 100 实时快递查询 Resp DTO
  15 + *
  16 + * 参见 <a href="https://api.kuaidi100.com/document/5f0ffb5ebc8da837cbd8aefc">快递 100 文档</a>
10 * 17 *
11 * @author jason 18 * @author jason
12 */ 19 */
@@ -39,21 +46,26 @@ public class Kd100ExpressQueryRespDTO { @@ -39,21 +46,26 @@ public class Kd100ExpressQueryRespDTO {
39 */ 46 */
40 private String message; 47 private String message;
41 48
  49 + /**
  50 + * 轨迹数组
  51 + */
42 @JsonProperty("data") 52 @JsonProperty("data")
43 private List<ExpressTrack> tracks; 53 private List<ExpressTrack> tracks;
44 54
45 @Data 55 @Data
46 public static class ExpressTrack { 56 public static class ExpressTrack {
  57 +
47 /** 58 /**
48 * 轨迹发生时间 59 * 轨迹发生时间
49 */ 60 */
50 - @JsonProperty("time")  
51 - private String time; 61 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  62 + private LocalDateTime time;
  63 +
52 /** 64 /**
53 * 轨迹描述 65 * 轨迹描述
54 */ 66 */
55 - @JsonProperty("context")  
56 - private String state; 67 + private String context;
  68 +
57 } 69 }
58 70
59 } 71 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/dto/kdniao/KdNiaoExpressQueryRespDTO.java
1 package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao; 1 package cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.kdniao;
2 2
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
3 import com.fasterxml.jackson.annotation.JsonProperty; 4 import com.fasterxml.jackson.annotation.JsonProperty;
  5 +import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
  6 +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
4 import lombok.Data; 7 import lombok.Data;
5 8
  9 +import java.time.LocalDateTime;
6 import java.util.List; 10 import java.util.List;
7 11
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
  14 +
8 /** 15 /**
9 - * 快递鸟快递查询 Resp DTO 参见 <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/wugo6k">快递鸟接口文档</a> 16 + * 快递鸟快递查询 Resp DTO
  17 + *
  18 + * 参见 <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/wugo6k">快递鸟接口文档</a>
10 * 19 *
11 * @author jason 20 * @author jason
12 */ 21 */
@@ -17,7 +26,7 @@ public class KdNiaoExpressQueryRespDTO { @@ -17,7 +26,7 @@ public class KdNiaoExpressQueryRespDTO {
17 * 快递公司编码 26 * 快递公司编码
18 */ 27 */
19 @JsonProperty("ShipperCode") 28 @JsonProperty("ShipperCode")
20 - private String expressCompanyCode; 29 + private String shipperCode;
21 30
22 /** 31 /**
23 * 快递单号 32 * 快递单号
@@ -31,10 +40,26 @@ public class KdNiaoExpressQueryRespDTO { @@ -31,10 +40,26 @@ public class KdNiaoExpressQueryRespDTO {
31 @JsonProperty("OrderCode") 40 @JsonProperty("OrderCode")
32 private String orderNo; 41 private String orderNo;
33 42
  43 + /**
  44 + * 用户 ID
  45 + */
34 @JsonProperty("EBusinessID") 46 @JsonProperty("EBusinessID")
35 private String businessId; 47 private String businessId;
  48 +
  49 + /**
  50 + * 普通物流状态
  51 + *
  52 + * 0 - 暂无轨迹信息
  53 + * 1 - 已揽收
  54 + * 2 - 在途中
  55 + * 3 - 签收
  56 + * 4 - 问题件
  57 + * 5 - 转寄
  58 + * 6 - 清关
  59 + */
36 @JsonProperty("State") 60 @JsonProperty("State")
37 private String state; 61 private String state;
  62 +
38 /** 63 /**
39 * 成功与否 64 * 成功与否
40 */ 65 */
@@ -46,30 +71,29 @@ public class KdNiaoExpressQueryRespDTO { @@ -46,30 +71,29 @@ public class KdNiaoExpressQueryRespDTO {
46 @JsonProperty("Reason") 71 @JsonProperty("Reason")
47 private String reason; 72 private String reason;
48 73
  74 + /**
  75 + * 轨迹数组
  76 + */
49 @JsonProperty("Traces") 77 @JsonProperty("Traces")
50 private List<ExpressTrack> tracks; 78 private List<ExpressTrack> tracks;
51 79
52 @Data 80 @Data
53 public static class ExpressTrack { 81 public static class ExpressTrack {
  82 +
54 /** 83 /**
55 - * 轨迹发生时间 84 + * 发生时间
56 */ 85 */
57 @JsonProperty("AcceptTime") 86 @JsonProperty("AcceptTime")
58 - private String time; 87 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
  88 + @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  89 + private LocalDateTime acceptTime;
  90 +
59 /** 91 /**
60 * 轨迹描述 92 * 轨迹描述
61 */ 93 */
62 @JsonProperty("AcceptStation") 94 @JsonProperty("AcceptStation")
63 - private String state; 95 + private String acceptStation;
  96 +
64 } 97 }
65 98
66 -// {  
67 -// "EBusinessID": "1237100",  
68 -// "Traces": [],  
69 -// "State": "0",  
70 -// "ShipperCode": "STO",  
71 -// "LogisticCode": "638650888018",  
72 -// "Success": true,  
73 -// "Reason": "暂无轨迹信息"  
74 -// }  
75 } 99 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kd100/Kd100ExpressClient.java
@@ -40,18 +40,24 @@ public class Kd100ExpressClient implements ExpressClient { @@ -40,18 +40,24 @@ public class Kd100ExpressClient implements ExpressClient {
40 private final RestTemplate restTemplate; 40 private final RestTemplate restTemplate;
41 private final TradeExpressProperties.Kd100Config config; 41 private final TradeExpressProperties.Kd100Config config;
42 42
  43 + /**
  44 + * 查询快递轨迹
  45 + *
  46 + * @see <a href="https://api.kuaidi100.com/debug-tool/query/">接口文档</a>
  47 + *
  48 + * @param reqDTO 查询请求参数
  49 + * @return 快递轨迹
  50 + */
43 @Override 51 @Override
44 public List<ExpressTrackRespDTO> getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) { 52 public List<ExpressTrackRespDTO> getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) {
45 - // 发起查询  
46 - Kd100ExpressQueryReqDTO kd100ReqParam = INSTANCE.convert2(reqDTO);  
47 - kd100ReqParam.setExpressCode(kd100ReqParam.getExpressCode().toLowerCase()); // 快递公司编码需要转成小写  
48 - Kd100ExpressQueryRespDTO respDTO = requestExpressQuery(REAL_TIME_QUERY_URL, kd100ReqParam, 53 + // 发起请求
  54 + Kd100ExpressQueryReqDTO requestDTO = INSTANCE.convert2(reqDTO)
  55 + .setExpressCode(reqDTO.getExpressCode().toLowerCase());
  56 + Kd100ExpressQueryRespDTO respDTO = httpRequest(REAL_TIME_QUERY_URL, requestDTO,
49 Kd100ExpressQueryRespDTO.class); 57 Kd100ExpressQueryRespDTO.class);
50 - log.debug("[getExpressTrackList][快递 100 接口 查询接口返回 {}]", respDTO);  
51 58
52 // 处理结果 59 // 处理结果
53 if (Objects.equals("false", respDTO.getResult())) { 60 if (Objects.equals("false", respDTO.getResult())) {
54 - log.error("[getExpressTrackList][快递 100 接口 返回失败 {}]", respDTO.getMessage());  
55 throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage()); 61 throw exception(EXPRESS_API_QUERY_FAILED, respDTO.getMessage());
56 } 62 }
57 if (CollUtil.isEmpty(respDTO.getTracks())) { 63 if (CollUtil.isEmpty(respDTO.getTracks())) {
@@ -61,7 +67,7 @@ public class Kd100ExpressClient implements ExpressClient { @@ -61,7 +67,7 @@ public class Kd100ExpressClient implements ExpressClient {
61 } 67 }
62 68
63 /** 69 /**
64 - * 发送快递 100 实时快递查询请求,可以作为通用快递 100 通用请求接口。 目前没有其它场景需要使用。暂时放这里 70 + * 快递 100 API 请求
65 * 71 *
66 * @param url 请求 url 72 * @param url 请求 url
67 * @param req 对应请求的请求参数 73 * @param req 对应请求的请求参数
@@ -69,24 +75,23 @@ public class Kd100ExpressClient implements ExpressClient { @@ -69,24 +75,23 @@ public class Kd100ExpressClient implements ExpressClient {
69 * @param <Req> 每个请求的请求结构 Req DTO 75 * @param <Req> 每个请求的请求结构 Req DTO
70 * @param <Resp> 每个请求的响应结构 Resp DTO 76 * @param <Resp> 每个请求的响应结构 Resp DTO
71 */ 77 */
72 - private <Req, Resp> Resp requestExpressQuery(String url, Req req, Class<Resp> respClass) { 78 + private <Req, Resp> Resp httpRequest(String url, Req req, Class<Resp> respClass) {
73 // 请求头 79 // 请求头
74 HttpHeaders headers = new HttpHeaders(); 80 HttpHeaders headers = new HttpHeaders();
75 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); 81 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
76 - // 生成签名  
77 - String param = JsonUtils.toJsonString(req);  
78 - String sign = generateReqSign(param, config.getKey(), config.getCustomer());  
79 // 请求体 82 // 请求体
  83 + String param = JsonUtils.toJsonString(req);
  84 + String sign = generateReqSign(param, config.getKey(), config.getCustomer()); // 签名
80 MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>(); 85 MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
81 requestBody.add("customer", config.getCustomer()); 86 requestBody.add("customer", config.getCustomer());
82 requestBody.add("sign", sign); 87 requestBody.add("sign", sign);
83 requestBody.add("param", param); 88 requestBody.add("param", param);
84 - log.debug("[sendExpressQueryReq][快递 100 接口的请求参数: {}]", requestBody); 89 + log.debug("[httpRequest][请求参数({})]", requestBody);
  90 +
85 // 发送请求 91 // 发送请求
86 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers); 92 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
87 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); 93 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
88 - log.debug("[sendExpressQueryReq][快递 100 接口响应结果 {}]", responseEntity);  
89 - 94 + log.debug("[httpRequest][的响应结果({})]", responseEntity);
90 // 处理响应 95 // 处理响应
91 if (!responseEntity.getStatusCode().is2xxSuccessful()) { 96 if (!responseEntity.getStatusCode().is2xxSuccessful()) {
92 throw exception(EXPRESS_API_QUERY_ERROR); 97 throw exception(EXPRESS_API_QUERY_ERROR);
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/kdniao/KdNiaoExpressClient.java
@@ -41,46 +41,49 @@ public class KdNiaoExpressClient implements ExpressClient { @@ -41,46 +41,49 @@ public class KdNiaoExpressClient implements ExpressClient {
41 * 快递鸟即时查询免费版 RequestType 41 * 快递鸟即时查询免费版 RequestType
42 */ 42 */
43 private static final String REAL_TIME_FREE_REQ_TYPE = "1002"; 43 private static final String REAL_TIME_FREE_REQ_TYPE = "1002";
  44 +
44 private final RestTemplate restTemplate; 45 private final RestTemplate restTemplate;
45 private final TradeExpressProperties.KdNiaoConfig config; 46 private final TradeExpressProperties.KdNiaoConfig config;
46 47
47 /** 48 /**
48 - * 快递鸟即时查询免费版本 49 + * 查询快递轨迹【免费版】
  50 + *
  51 + * 仅支持 3 家:申通快递、圆通速递、百世快递
  52 + *
  53 + * @see <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/wugo6k">接口文档</a>
49 * 54 *
50 - * @see <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/wugo6k">快递鸟接口文档</a>  
51 * @param reqDTO 查询请求参数 55 * @param reqDTO 查询请求参数
  56 + * @return 快递轨迹
52 */ 57 */
53 @Override 58 @Override
54 public List<ExpressTrackRespDTO> getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) { 59 public List<ExpressTrackRespDTO> getExpressTrackList(ExpressTrackQueryReqDTO reqDTO) {
55 - KdNiaoExpressQueryReqDTO kdNiaoReqData = INSTANCE.convert(reqDTO);  
56 - // 快递公司编码需要转成大写  
57 - kdNiaoReqData.setExpressCode(reqDTO.getExpressCode().toUpperCase());  
58 - KdNiaoExpressQueryRespDTO respDTO = requestKdNiaoApi(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE,  
59 - kdNiaoReqData, KdNiaoExpressQueryRespDTO.class);  
60 - log.debug("[getExpressTrackList][快递鸟即时查询接口返回 {}]", respDTO); 60 + // 发起请求
  61 + KdNiaoExpressQueryReqDTO requestDTO = INSTANCE.convert(reqDTO)
  62 + .setExpressCode(reqDTO.getExpressCode().toUpperCase());
  63 + KdNiaoExpressQueryRespDTO respDTO = httpRequest(REAL_TIME_QUERY_URL, REAL_TIME_FREE_REQ_TYPE,
  64 + requestDTO, KdNiaoExpressQueryRespDTO.class);
61 65
62 // 处理结果 66 // 处理结果
63 if (respDTO == null || !respDTO.getSuccess()) { 67 if (respDTO == null || !respDTO.getSuccess()) {
64 throw exception(EXPRESS_API_QUERY_FAILED, respDTO == null ? "" : respDTO.getReason()); 68 throw exception(EXPRESS_API_QUERY_FAILED, respDTO == null ? "" : respDTO.getReason());
65 } 69 }
66 - if (CollUtil.isNotEmpty(respDTO.getTracks())) { 70 + if (CollUtil.isEmpty(respDTO.getTracks())) {
67 return Collections.emptyList(); 71 return Collections.emptyList();
68 } 72 }
69 return INSTANCE.convertList(respDTO.getTracks()); 73 return INSTANCE.convertList(respDTO.getTracks());
70 } 74 }
71 75
72 /** 76 /**
73 - * 快递鸟 通用的 API 请求,暂时没有其他应用场景, 暂时放这里 77 + * 快递鸟 API 请求
74 * 78 *
75 * @param url 请求 url 79 * @param url 请求 url
76 - * @param requestType 对应的请求指令 (快递鸟的RequestType) 80 + * @param requestType 对应的请求指令 (快递鸟的 RequestType)
77 * @param req 对应请求的请求参数 81 * @param req 对应请求的请求参数
78 * @param respClass 对应请求的响应 class 82 * @param respClass 对应请求的响应 class
79 * @param <Req> 每个请求的请求结构 Req DTO 83 * @param <Req> 每个请求的请求结构 Req DTO
80 * @param <Resp> 每个请求的响应结构 Resp DTO 84 * @param <Resp> 每个请求的响应结构 Resp DTO
81 */ 85 */
82 - private <Req, Resp> Resp requestKdNiaoApi(String url, String requestType, Req req,  
83 - Class<Resp> respClass){ 86 + private <Req, Resp> Resp httpRequest(String url, String requestType, Req req, Class<Resp> respClass) {
84 // 请求头 87 // 请求头
85 HttpHeaders headers = new HttpHeaders(); 88 HttpHeaders headers = new HttpHeaders();
86 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); 89 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
@@ -93,11 +96,12 @@ public class KdNiaoExpressClient implements ExpressClient { @@ -93,11 +96,12 @@ public class KdNiaoExpressClient implements ExpressClient {
93 requestBody.add("EBusinessID", config.getBusinessId()); 96 requestBody.add("EBusinessID", config.getBusinessId());
94 requestBody.add("DataSign", dataSign); 97 requestBody.add("DataSign", dataSign);
95 requestBody.add("RequestType", requestType); 98 requestBody.add("RequestType", requestType);
96 - log.debug("[requestKdNiaoApi][快递鸟接口 RequestType : {}, 的请求参数 {}]", requestType, requestBody); 99 + log.debug("[httpRequest][RequestType({}) 的请求参数({})]", requestType, requestBody);
  100 +
97 // 发送请求 101 // 发送请求
98 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers); 102 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
99 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); 103 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
100 - log.debug("快递鸟接口 RequestType : {}, 的响应结果 {}", requestType, responseEntity); 104 + log.debug("[httpRequest][RequestType({}) 的响应结果({})", requestType, responseEntity);
101 // 处理响应 105 // 处理响应
102 if (!responseEntity.getStatusCode().is2xxSuccessful()) { 106 if (!responseEntity.getStatusCode().is2xxSuccessful()) {
103 throw exception(EXPRESS_API_QUERY_ERROR); 107 throw exception(EXPRESS_API_QUERY_ERROR);
@@ -106,7 +110,10 @@ public class KdNiaoExpressClient implements ExpressClient { @@ -106,7 +110,10 @@ public class KdNiaoExpressClient implements ExpressClient {
106 } 110 }
107 111
108 /** 112 /**
109 - * 快递鸟生成请求签名 参见 <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/zes04h">签名说明</a> 113 + * 快递鸟生成请求签名
  114 + *
  115 + * 参见 <a href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/zes04h">签名说明</a>
  116 + *
110 * @param reqData 请求实体 117 * @param reqData 请求实体
111 * @param apiKey api Key 118 * @param apiKey api Key
112 */ 119 */
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.order;
  2 +
  3 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * 交易订单【读】 Service 接口
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +public interface TradeOrderQueryService {
  13 +
  14 + /**
  15 + * 获得订单的物流轨迹
  16 + *
  17 + * @param id 订单编号
  18 + * @param userId 用户编号
  19 + * @return 物流轨迹数组
  20 + */
  21 + List<ExpressTrackRespDTO> getExpressTrackList(Long id, Long userId);
  22 +
  23 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.order;
  2 +
  3 +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
  4 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
  5 +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
  6 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory;
  7 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;
  8 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
  9 +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
  10 +import org.springframework.stereotype.Service;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.Collections;
  14 +import java.util.List;
  15 +
  16 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  17 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.EXPRESS_NOT_EXISTS;
  18 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
  19 +
  20 +/**
  21 + * 交易订单【读】 Service 实现类
  22 + *
  23 + * @author 芋道源码
  24 + */
  25 +@Service
  26 +public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
  27 +
  28 + @Resource
  29 + private ExpressClientFactory expressClientFactory;
  30 +
  31 + @Resource
  32 + private TradeOrderMapper tradeOrderMapper;
  33 +
  34 + @Resource
  35 + private DeliveryExpressService deliveryExpressService;
  36 +
  37 + @Override
  38 + public List<ExpressTrackRespDTO> getExpressTrackList(Long id, Long userId) {
  39 + // 查询订单
  40 + TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId);
  41 + if (order == null) {
  42 + throw exception(ORDER_NOT_FOUND);
  43 + }
  44 +
  45 + // 查询物流公司
  46 + if (order.getLogisticsId() == null) {
  47 + return Collections.emptyList();
  48 + }
  49 + DeliveryExpressDO express = deliveryExpressService.getDeliveryExpress(order.getLogisticsId());
  50 + if (express == null) {
  51 + throw exception(EXPRESS_NOT_EXISTS);
  52 + }
  53 +
  54 + // 查询物流轨迹
  55 + return expressClientFactory.getDefaultExpressClient().getExpressTrackList(
  56 + new ExpressTrackQueryReqDTO().setExpressCode(express.getCode()).setLogisticsNo(order.getLogisticsNo())
  57 + .setPhone(order.getReceiverMobile()));
  58 + }
  59 +
  60 +}
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties;
  5 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;
  6 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
  7 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kd100.Kd100ExpressClient;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.junit.jupiter.api.BeforeEach;
  10 +import org.junit.jupiter.api.Disabled;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.boot.web.client.RestTemplateBuilder;
  13 +import org.springframework.web.client.RestTemplate;
  14 +
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * {@link Kd100ExpressClient} 的集成测试
  19 + *
  20 + * @author jason
  21 + */
  22 +@Slf4j
  23 +public class Kd100ExpressClientIntegrationTest {
  24 +
  25 + private Kd100ExpressClient client;
  26 +
  27 + @BeforeEach
  28 + public void init() {
  29 + RestTemplate restTemplate = new RestTemplateBuilder().build();
  30 + TradeExpressProperties.Kd100Config config = new TradeExpressProperties.Kd100Config()
  31 + .setKey("pLXUGAwK5305")
  32 + .setCustomer("E77DF18BE109F454A5CD319E44BF5177");
  33 + client = new Kd100ExpressClient(restTemplate, config);
  34 + }
  35 +
  36 + @Test
  37 + @Disabled("集成测试,暂时忽略")
  38 + public void testGetExpressTrackList() {
  39 + ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO();
  40 + reqDTO.setExpressCode("STO");
  41 + reqDTO.setLogisticsNo("773220402764314");
  42 + List<ExpressTrackRespDTO> tracks = client.getExpressTrackList(reqDTO);
  43 + System.out.println(JsonUtils.toJsonPrettyString(tracks));
  44 + }
  45 +
  46 +}
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/Kd100ExpressClientTest.java deleted
1 -package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl;  
2 -  
3 -import cn.iocoder.yudao.framework.common.exception.ServiceException;  
4 -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties;  
5 -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;  
6 -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kd100.Kd100ExpressClient;  
7 -import org.junit.jupiter.api.BeforeEach;  
8 -import org.junit.jupiter.api.Disabled;  
9 -import org.junit.jupiter.api.Test;  
10 -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;  
11 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
12 -import org.springframework.boot.test.context.SpringBootTest;  
13 -import org.springframework.boot.web.client.RestTemplateBuilder;  
14 -import org.springframework.context.annotation.Import;  
15 -import org.springframework.test.context.ActiveProfiles;  
16 -  
17 -import javax.annotation.Resource;  
18 -  
19 -import static org.junit.jupiter.api.Assertions.assertEquals;  
20 -import static org.junit.jupiter.api.Assertions.assertThrows;  
21 -  
22 -// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器  
23 -/**  
24 - * @author jason  
25 - */  
26 -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = Kd100ExpressClientTest.Application.class)  
27 -@ActiveProfiles("unit-test") // 设置使用 trade-delivery-query 配置文件  
28 -public class Kd100ExpressClientTest {  
29 -  
30 - @Resource  
31 - private RestTemplateBuilder builder;  
32 - @Resource  
33 - private TradeExpressProperties expressQueryProperties;  
34 -  
35 - private Kd100ExpressClient kd100ExpressClient;  
36 -  
37 - @BeforeEach  
38 - public void init(){  
39 - kd100ExpressClient = new Kd100ExpressClient(builder.build(),expressQueryProperties.getKd100());  
40 - }  
41 - @Test  
42 - @Disabled("需要 授权 key. 暂时忽略")  
43 - void testRealTimeQueryExpressFailed() {  
44 - ServiceException t = assertThrows(ServiceException.class, () -> {  
45 - ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO();  
46 - reqDTO.setExpressCode("yto");  
47 - reqDTO.setLogisticsNo("YT9383342193097");  
48 - kd100ExpressClient.getExpressTrackList(reqDTO);  
49 - });  
50 - assertEquals(1011003005, t.getCode());  
51 - }  
52 -  
53 - @Import({  
54 - RestTemplateAutoConfiguration.class  
55 - })  
56 - @EnableConfigurationProperties(TradeExpressProperties.class)  
57 - public static class Application {  
58 - }  
59 -}  
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties;
  5 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;
  6 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
  7 +import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kdniao.KdNiaoExpressClient;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.junit.jupiter.api.BeforeEach;
  10 +import org.junit.jupiter.api.Disabled;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.boot.web.client.RestTemplateBuilder;
  13 +import org.springframework.web.client.RestTemplate;
  14 +
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * {@link KdNiaoExpressClient} 的集成测试
  19 + *
  20 + * @author jason
  21 + */
  22 +@Slf4j
  23 +public class KdNiaoExpressClientIntegrationTest {
  24 +
  25 + private KdNiaoExpressClient client;
  26 +
  27 + @BeforeEach
  28 + public void init() {
  29 + RestTemplate restTemplate = new RestTemplateBuilder().build();
  30 + TradeExpressProperties.KdNiaoConfig config = new TradeExpressProperties.KdNiaoConfig()
  31 + .setApiKey("cb022f1e-48f1-4c4a-a723-9001ac9676b8")
  32 + .setBusinessId("1809751");
  33 + client = new KdNiaoExpressClient(restTemplate, config);
  34 + }
  35 +
  36 + @Test
  37 + @Disabled("集成测试,暂时忽略")
  38 + public void testGetExpressTrackList() {
  39 + ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO();
  40 + reqDTO.setExpressCode("STO");
  41 + reqDTO.setLogisticsNo("663220402764314");
  42 + List<ExpressTrackRespDTO> tracks = client.getExpressTrackList(reqDTO);
  43 + System.out.println(JsonUtils.toJsonPrettyString(tracks));
  44 + }
  45 +
  46 +}
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/KdNiaoExpressClientTest.java deleted
1 -package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl;  
2 -  
3 -import cn.iocoder.yudao.framework.common.exception.ServiceException;  
4 -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties;  
5 -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;  
6 -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl.kdniao.KdNiaoExpressClient;  
7 -import org.junit.jupiter.api.BeforeEach;  
8 -import org.junit.jupiter.api.Disabled;  
9 -import org.junit.jupiter.api.Test;  
10 -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;  
11 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
12 -import org.springframework.boot.test.context.SpringBootTest;  
13 -import org.springframework.boot.web.client.RestTemplateBuilder;  
14 -import org.springframework.context.annotation.Import;  
15 -import org.springframework.test.context.ActiveProfiles;  
16 -  
17 -import javax.annotation.Resource;  
18 -  
19 -import static org.junit.jupiter.api.Assertions.assertThrows;  
20 -  
21 -// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器  
22 -/**  
23 - * {@link KdNiaoExpressClient} 的单元测试  
24 - *  
25 - * @author jason  
26 - */  
27 -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = KdNiaoExpressClientTest.Application.class)  
28 -@ActiveProfiles("unit-test")  
29 -public class KdNiaoExpressClientTest {  
30 -  
31 - @Resource  
32 - private RestTemplateBuilder builder;  
33 - @Resource  
34 - private TradeExpressProperties expressQueryProperties;  
35 -  
36 - private KdNiaoExpressClient kdNiaoExpressClient;  
37 -  
38 - @BeforeEach  
39 - public void init(){  
40 - kdNiaoExpressClient = new KdNiaoExpressClient(builder.build(),expressQueryProperties.getKdNiao());  
41 - }  
42 - @Test  
43 - @Disabled("需要 授权 key. 暂时忽略")  
44 - void testRealTimeQueryExpressFailed() {  
45 - assertThrows(ServiceException.class,() ->{  
46 - ExpressTrackQueryReqDTO reqDTO = new ExpressTrackQueryReqDTO();  
47 - reqDTO.setExpressCode("yy");  
48 - reqDTO.setLogisticsNo("YT9383342193097");  
49 - kdNiaoExpressClient.getExpressTrackList(reqDTO);  
50 - });  
51 - }  
52 -  
53 - @Import({  
54 - RestTemplateAutoConfiguration.class  
55 - })  
56 - @EnableConfigurationProperties(TradeExpressProperties.class)  
57 - public static class Application {  
58 - }  
59 -}  
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/framework/delivery/core/client/impl/NoProvideExpressClientTest.java deleted
1 -package cn.iocoder.yudao.module.trade.framework.delivery.core.client.impl;  
2 -  
3 -import cn.iocoder.yudao.framework.common.exception.ServiceException;  
4 -import cn.iocoder.yudao.module.trade.framework.delivery.config.ExpressClientConfig;  
5 -import cn.iocoder.yudao.module.trade.framework.delivery.config.TradeExpressProperties;  
6 -import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClient;  
7 -import org.junit.jupiter.api.Test;  
8 -import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;  
9 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
10 -import org.springframework.boot.test.context.SpringBootTest;  
11 -import org.springframework.boot.web.client.RestTemplateBuilder;  
12 -import org.springframework.context.annotation.Bean;  
13 -import org.springframework.context.annotation.Import;  
14 -import org.springframework.test.context.ActiveProfiles;  
15 -import org.springframework.web.client.RestTemplate;  
16 -  
17 -import javax.annotation.Resource;  
18 -  
19 -import static org.junit.jupiter.api.Assertions.assertEquals;  
20 -import static org.junit.jupiter.api.Assertions.assertThrows;  
21 -  
22 -// TODO @jason:可以参考 AliyunSmsClientTest 写,纯 mockito,无需启动 spring 容器  
23 -/**  
24 - * @author jason  
25 - */  
26 -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = NoProvideExpressClientTest.Application.class)  
27 -@ActiveProfiles("unit-test") // 设置使用 trade-delivery-query 配置文件  
28 -@Import({ExpressClientConfig.class})  
29 -public class NoProvideExpressClientTest {  
30 -  
31 - @Resource  
32 - private ExpressClient expressClient;  
33 -  
34 - @Test  
35 - void getExpressTrackList() {  
36 - ServiceException t = assertThrows(ServiceException.class, () -> {  
37 - expressClient.getExpressTrackList(null);  
38 - });  
39 - assertEquals(1011003006, t.getCode());  
40 - }  
41 -  
42 - @Import({  
43 - RestTemplateAutoConfiguration.class,  
44 - })  
45 - @EnableConfigurationProperties(TradeExpressProperties.class)  
46 - public static class Application {  
47 -  
48 - @Bean  
49 - private RestTemplate restTemplate(RestTemplateBuilder builder) {  
50 - return builder.build();  
51 - }  
52 - }  
53 -}  
yudao-server/src/main/resources/application.yaml
@@ -204,6 +204,14 @@ yudao: @@ -204,6 +204,14 @@ yudao:
204 order: 204 order:
205 app-id: 1 # 商户编号 205 app-id: 1 # 商户编号
206 expire-time: 2h # 支付的过期时间 206 expire-time: 2h # 支付的过期时间
  207 + express:
  208 + client: kd_niao
  209 + kd-niao:
  210 + api-key: cb022f1e-48f1-4c4a-a723-9001ac9676b8
  211 + business-id: 1809751
  212 + kd100:
  213 + key: pLXUGAwK5305
  214 + customer: E77DF18BE109F454A5CD319E44BF5177
207 215
208 debug: false 216 debug: false
209 217