From 6bd48f2e6205df55d85df2ddb72324e112a3a772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=AE=87=E5=A5=87?= Date: Tue, 29 Apr 2025 22:30:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=89=A9=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/express/ExpressInterceptReqDTO.java | 19 +++ .../com/ruoyi/xkt/manager/ExpressManager.java | 10 +- .../manager/impl/YtoExpressManagerImpl.java | 33 +++- .../manager/impl/ZtoExpressManagerImpl.java | 148 +++++++++++++++++- .../service/impl/StoreOrderServiceImpl.java | 20 +-- .../yto/YtoInterceptReturnParam.java | 19 +++ .../zto/ZtoInterceptReturnParam.java | 27 ++++ 7 files changed, 263 insertions(+), 13 deletions(-) create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/express/ExpressInterceptReqDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/thirdpart/yto/YtoInterceptReturnParam.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/thirdpart/zto/ZtoInterceptReturnParam.java diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/express/ExpressInterceptReqDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/express/ExpressInterceptReqDTO.java new file mode 100644 index 000000000..83417346d --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/express/ExpressInterceptReqDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.dto.express; + +import lombok.Data; + +/** + * @author liangyq + * @date 2025-04-29 17:57 + */ +@Data +public class ExpressInterceptReqDTO { + /** + * 请求号 + */ + private String expressReqNo; + /** + * 运单号 + */ + private String expressWaybillNo; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/ExpressManager.java b/xkt/src/main/java/com/ruoyi/xkt/manager/ExpressManager.java index a12e61a43..0aee1798b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/ExpressManager.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/ExpressManager.java @@ -1,6 +1,7 @@ package com.ruoyi.xkt.manager; import com.ruoyi.xkt.dto.express.ExpressCancelReqDTO; +import com.ruoyi.xkt.dto.express.ExpressInterceptReqDTO; import com.ruoyi.xkt.dto.express.ExpressPrintDTO; import com.ruoyi.xkt.dto.express.ExpressShipReqDTO; import com.ruoyi.xkt.enums.EExpressChannel; @@ -34,7 +35,14 @@ public interface ExpressManager { * @param cancelReqDTO * @return */ - boolean cancelShipOrder(ExpressCancelReqDTO cancelReqDTO); + boolean cancelShip(ExpressCancelReqDTO cancelReqDTO); + + /** + * 拦截 + * + * @return + */ + boolean interceptShip(ExpressInterceptReqDTO interceptReqDTO); /** * 打印面单 diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/YtoExpressManagerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/YtoExpressManagerImpl.java index 4dd042adb..6d9eae6bb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/YtoExpressManagerImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/YtoExpressManagerImpl.java @@ -7,6 +7,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.xkt.dto.express.ExpressCancelReqDTO; +import com.ruoyi.xkt.dto.express.ExpressInterceptReqDTO; import com.ruoyi.xkt.dto.express.ExpressPrintDTO; import com.ruoyi.xkt.dto.express.ExpressShipReqDTO; import com.ruoyi.xkt.enums.EExpressChannel; @@ -74,7 +75,7 @@ public class YtoExpressManagerImpl implements ExpressManager { } @Override - public boolean cancelShipOrder(ExpressCancelReqDTO cancelReqDTO) { + public boolean cancelShip(ExpressCancelReqDTO cancelReqDTO) { Assert.notNull(cancelReqDTO); Assert.notEmpty(cancelReqDTO.getExpressReqNo()); YtoCancelOrderParam cancelOrderParam = new YtoCancelOrderParam(); @@ -104,6 +105,36 @@ public class YtoExpressManagerImpl implements ExpressManager { return false; } + @Override + public boolean interceptShip(ExpressInterceptReqDTO interceptReqDTO) { + Assert.notNull(interceptReqDTO); + Assert.notEmpty(interceptReqDTO.getExpressWaybillNo()); + YtoInterceptReturnParam interceptReturnParam = new YtoInterceptReturnParam(); + interceptReturnParam.setWaybillNo(interceptReqDTO.getExpressWaybillNo()); + interceptReturnParam.setWantedDesc("拦截退回"); + try { + String param = JSONUtil.toJsonStr(interceptReturnParam); + String sign = YtoSignUtil.sign("wanted_report_adapter", "v1", param, appSecret); + YtoPublicRequest request = YtoPublicRequest.builder() + .timestamp(System.currentTimeMillis()) + .param(param) + .format(YtoPublicRequest.EFormat.JSON) + .sign(sign).build(); + String rtnStr = HttpUtil.post(gatewayUrl + "open/wanted_report_adapter/v1/N364gM/" + appKey, + JSONUtil.toJsonStr(request)); + log.info("圆通订单拦截返回信息: {}", rtnStr); + JSONObject rtnJson = JSONUtil.parseObj(rtnStr); + Integer statusCode = rtnJson.getInt("statusCode"); + if (statusCode != null && statusCode == 0) { + return true; + } + } catch (Exception e) { + log.error("圆通订单拦截异常", e); + } + log.warn("圆通订单拦截失败: {}", interceptReqDTO); + return false; + } + @Override public List printOrder(Collection waybillNos) { Assert.notEmpty(waybillNos); diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/ZtoExpressManagerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/ZtoExpressManagerImpl.java index 9fecc4d87..c4a6a2b22 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/ZtoExpressManagerImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/ZtoExpressManagerImpl.java @@ -2,12 +2,14 @@ package com.ruoyi.xkt.manager.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.xkt.dto.express.ExpressCancelReqDTO; +import com.ruoyi.xkt.dto.express.ExpressInterceptReqDTO; import com.ruoyi.xkt.dto.express.ExpressPrintDTO; import com.ruoyi.xkt.dto.express.ExpressShipReqDTO; import com.ruoyi.xkt.enums.EExpressChannel; @@ -36,6 +38,8 @@ public class ZtoExpressManagerImpl implements ExpressManager, InitializingBean { private static final String CANCEL_ORDER_URI = "zto.open.cancelPreOrder"; + private static final String INTERCEPT_URI = "thirdcenter.createIntercept"; + private static final String STRUCTURE_ADDRESS_URI = "zto.innovate.structureNamePhoneAddress"; public static final String ORDER_PRINT_URI = "zto.open.order.print"; @@ -90,7 +94,7 @@ public class ZtoExpressManagerImpl implements ExpressManager, InitializingBean { } @Override - public boolean cancelShipOrder(ExpressCancelReqDTO cancelReqDTO) { + public boolean cancelShip(ExpressCancelReqDTO cancelReqDTO) { Assert.notNull(cancelReqDTO); Assert.notEmpty(cancelReqDTO.getExpressWaybillNo()); ZtoCancelOrderParam cancelOrderParam = new ZtoCancelOrderParam(); @@ -115,6 +119,148 @@ public class ZtoExpressManagerImpl implements ExpressManager, InitializingBean { return false; } + @Override + public boolean interceptShip(ExpressInterceptReqDTO interceptReqDTO) { + Assert.notNull(interceptReqDTO); + Assert.notEmpty(interceptReqDTO.getExpressWaybillNo()); + Assert.notEmpty(interceptReqDTO.getExpressReqNo()); + ZtoInterceptReturnParam interceptReturnParam = new ZtoInterceptReturnParam(); + interceptReturnParam.setBillCode(interceptReqDTO.getExpressWaybillNo()); + interceptReturnParam.setRequestId(IdUtil.simpleUUID()); + interceptReturnParam.setDestinationType(1); + interceptReturnParam.setThirdBizNo(interceptReqDTO.getExpressReqNo()); + ZopPublicRequest request = new ZopPublicRequest(); + request.setBody(JSONUtil.toJsonStr(interceptReturnParam)); + request.setUrl(gatewayUrl + INTERCEPT_URI); + request.setEncryptionType(EncryptionType.MD5); + try { + String bodyStr = client.execute(request); + log.info("中通订单拦截返回信息: {}", bodyStr); + /** + * E23101 + * 快件已签收 + * 更换未签收运单发起 + * E23102 + * 订单信息不存在 + * 联系管理员处理 + * E23108 + * 无效的拦截、退改方式 + * 检查入参destinationType + * E23110 + * 无揽收与面单使用网点 + * 联系管理员处理 + * E23111 + * 时效件,无法拦截 + * 更换运单 + * E23112 + * 已第三方进站不允许拦截 + * 更换运单 + * E23113 + * 有转单信息不允许拦截 + * 更换运单 + * E23114 + * 派件网点不支持到付业务 + * 更换运单 + * E23115 + * 派件网点不支持代收业务 + * 更换运单 + * E23116 + * 渠道不一致,不允许重复发起拦截/超过最大拦截次数 + * 更换运单 + * E23118 + * 订购渠道不存在/该渠道不允许拦截 + * 检查入参platform,如确认无误,联系管理员处理 + * E23119 + * 无任何轨迹不允许发起拦截 + * 揽收后再重试 + * E23120 + * 有派件扫描不允许拦截 + * 更换运单 + * E23121 + * 存在相同渠道的拦截件,不允许再次发起 + * 更换运单 + * E23122 + * 目的地停发不允许拦截 + * 更换运单 + * E23123 + * 存在退改件信息不允许拦截 + * 更换运单 + * E23124 + * 轨迹异常不允许拦截 + * 更换运单 + * E23127 + * 已经有相同诉求,不允许再次发起 + * 更换运单或更改入参destinationType或改地址的收件地址 + * E23130 + * 非拦截中拦截件,不能取消 + * 此运单已无法取消拦截,如仍需取消,请再次拦截改回原址 + * E23131 + * 取消网点与订购网点或原单揽收网点不一致,不能取消 + * 联系管理员处理 + * E23135 + * 同拦截发起方不一致,无权取消 + * 联系管理员处理 + * E23136 + * 已发往港澳台,暂不允许拦截 + * 更换运单 + * E23137 + * 有派件网点到件不允许拦截 + * 更换运单 + * E23138 + * 国际件不允许发起拦截 + * 更换运单 + * E23139 + * 不满足拦截发起业务规则 + * 更换运单 + * E23140 + * 包裹已确认遗失 + * 更换运单 + * E23141 + * 包裹已确认弃件 + * 更换运单 + * E23144 + * CRM无权限 + * 联系合作网点在客户管理系统开通拦截权限 + * E23146 + * 跨境客户,不允许发起改地址/退回指定地址 + * 更换运单 + * E23148 + * 联系方式格式错误,请检查后提交或不填写 + * 检查入参receivePhone + * E23149 + * 联系方式是虚拟号,请补全分机号或不填写 + * 检查入参receivePhone + * E23150 + * 联系方式超过16位,请删减 + * 检查入参receivePhone + * E23151 + * 已经有相同诉求,不允许再次发起 + * 更换运单或更改入参destinationType或改地址的收件地址 + * E23153 + * 发起人不属于发起网点 + * 联系管理员处理 + * E23154 + * 单号不属于当前网点,不允许发起 + * 联系管理员处理 + * E23157 + * 该渠道不支持重复发起拦截 + * 更换运单 + * E23160 + * 已存在外部平台发起的拦截,不允许发起 + * 更换运单 + */ + JSONObject bodyJson = JSONUtil.parseObj(bodyStr); + boolean success = bodyJson.getBool("status"); + if (success) { + return true; + } + } catch (Exception e) { + log.error("中通订单拦截异常", e); + } + log.warn("中通订单拦截失败: {}", interceptReqDTO); + return false; + } + @Override public List printOrder(Collection waybillNos) { Assert.notEmpty(waybillNos); diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index d77f7d450..4baf69406 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -609,11 +609,11 @@ public class StoreOrderServiceImpl implements IStoreOrderService { order.getOrderNo())); } } - if (EExpressType.STORE.getValue().equals(containDetail.getExpressType())) { - //已存在档口发货的明细 - throw new ServiceException(CharSequenceUtil.format("订单[{}]由档口物流发货!", - order.getOrderNo())); - } +// if (EExpressType.STORE.getValue().equals(containDetail.getExpressType())) { +// //已存在档口发货的明细 +// throw new ServiceException(CharSequenceUtil.format("订单[{}]由档口物流发货!", +// order.getOrderNo())); +// } } List orderDetails = storeOrderDetailMapper.selectByIds(storeOrderDetailIds); for (StoreOrderDetail orderDetail : orderDetails) { @@ -699,11 +699,11 @@ public class StoreOrderServiceImpl implements IStoreOrderService { order.getOrderNo())); } } - if (EExpressType.PLATFORM.getValue().equals(containDetail.getExpressType())) { - //已存在平台发货的明细 - throw new ServiceException(CharSequenceUtil.format("订单[{}]由平台物流发货!", - order.getOrderNo())); - } +// if (EExpressType.PLATFORM.getValue().equals(containDetail.getExpressType())) { +// //已存在平台发货的明细 +// throw new ServiceException(CharSequenceUtil.format("订单[{}]由平台物流发货!", +// order.getOrderNo())); +// } } List orderDetails = storeOrderDetailMapper.selectByIds(storeOrderDetailIds); List orderDetailIdList = new ArrayList<>(orderDetails.size()); diff --git a/xkt/src/main/java/com/ruoyi/xkt/thirdpart/yto/YtoInterceptReturnParam.java b/xkt/src/main/java/com/ruoyi/xkt/thirdpart/yto/YtoInterceptReturnParam.java new file mode 100644 index 000000000..1dcc78348 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/thirdpart/yto/YtoInterceptReturnParam.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.thirdpart.yto; + +import lombok.Data; + +/** + * @author liangyq + * @date 2025-04-29 18:13 + */ +@Data +public class YtoInterceptReturnParam { + /** + * 运单号码 + */ + private String waybillNo; + /** + * 问题描述 + */ + private String wantedDesc; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/thirdpart/zto/ZtoInterceptReturnParam.java b/xkt/src/main/java/com/ruoyi/xkt/thirdpart/zto/ZtoInterceptReturnParam.java new file mode 100644 index 000000000..d130eb81d --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/thirdpart/zto/ZtoInterceptReturnParam.java @@ -0,0 +1,27 @@ +package com.ruoyi.xkt.thirdpart.zto; + +import lombok.Data; + +/** + * @author liangyq + * @date 2025-04-29 18:13 + */ +@Data +public class ZtoInterceptReturnParam { + /** + * 运单号 + */ + private String billCode; + /** + * 请求ID(幂等校验) + */ + private String requestId; + /** + * 拦截类型:1 返回收件网点;2 返回寄件人地址;3 修改派送地址;4 退回指定地址(必填) + */ + private Integer destinationType; + /** + * 外部业务单号 + */ + private String thirdBizNo; +}