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