From 55acbed0cbc095260f97e697fde2504fcc4b1699 Mon Sep 17 00:00:00 2001
From: Joshi <3040996759@qq.com>
Date: Wed, 13 Aug 2025 13:57:59 +0800
Subject: [PATCH] =?UTF-8?q?feat(klp-wms):=20=E6=B7=BB=E5=8A=A0=E9=A1=BA?=
=?UTF-8?q?=E5=BF=83=E6=8D=B7=E8=BE=BE=E5=BF=AB=E9=80=92=E8=BD=A8=E8=BF=B9?=
=?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD-=20=E6=96=B0=E5=A2=9E=20Sx?=
=?UTF-8?q?jdRouteQueryUtil=20=E5=B7=A5=E5=85=B7=E7=B1=BB=EF=BC=8C?=
=?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=A1=BA=E5=BF=83=E6=8D=B7=E8=BE=BE=E5=BF=AB?=
=?UTF-8?q?=E9=80=92=E7=9A=84=E7=94=B5=E5=AD=90=E8=BF=90=E5=8D=95=E5=88=9B?=
=?UTF-8?q?=E5=BB=BA=E5=92=8C=E8=BD=A8=E8=BF=B9=E6=9F=A5=E8=AF=A2=20-=20?=
=?UTF-8?q?=E5=9C=A8=20WmsExpressServiceImpl=20=E4=B8=AD=E9=9B=86=E6=88=90?=
=?UTF-8?q?=E9=A1=BA=E5=BF=83=E6=8D=B7=E8=BE=BE=E7=9A=84=E8=BD=A8=E8=BF=B9?=
=?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD=20-=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=20jd-sdk=20=E4=BE=9D=E8=B5=96=EF=BC=8C=E7=94=A8=E4=BA=8E?=
=?UTF-8?q?=E9=A1=BA=E5=BF=83=E6=8D=B7=E8=BE=BE=E5=BF=AB=E9=80=92=E7=9A=84?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=93=8D=E4=BD=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
klp-wms/pom.xml | 6 +
.../service/impl/WmsExpressServiceImpl.java | 9 +
.../com/klp/utils/SxjdRouteQueryUtil.java | 287 ++++++++++++++++++
3 files changed, 302 insertions(+)
create mode 100644 klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
diff --git a/klp-wms/pom.xml b/klp-wms/pom.xml
index b49b1b64..ca58eb19 100644
--- a/klp-wms/pom.xml
+++ b/klp-wms/pom.xml
@@ -56,5 +56,11 @@
kfpt-sdk
1.0.0
+
+ com.jd
+ jd-sdk
+ 1.2.89
+ RELEASE
+
diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsExpressServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsExpressServiceImpl.java
index ab221e13..5e671410 100644
--- a/klp-wms/src/main/java/com/klp/service/impl/WmsExpressServiceImpl.java
+++ b/klp-wms/src/main/java/com/klp/service/impl/WmsExpressServiceImpl.java
@@ -238,6 +238,15 @@ public class WmsExpressServiceImpl implements IWmsExpressService {
WmsExpressVo.setLastStatus(stoVo.getFirstStatusName());
}
}
+ if (expressType.equals("SXJD") && WmsExpressVo.getStatus() == 1L) {
+ // 顺心捷达快递轨迹查询
+ String result = SxjdRouteQueryUtil.queryRoute(WmsExpressVo.getExpressCode());
+ WmsExpressVo sxjdVo = SxjdRouteQueryUtil.parseData(result);
+ if (sxjdVo != null) {
+ WmsExpressVo.setLastUpdateTime(sxjdVo.getLastUpdateTime());
+ WmsExpressVo.setLastStatus(sxjdVo.getLastStatus());
+ }
+ }
WmsExpress add = BeanUtil.toBean(WmsExpressVo, WmsExpress.class);
baseMapper.updateById(add);;
}
diff --git a/klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java b/klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
new file mode 100644
index 00000000..eac9855a
--- /dev/null
+++ b/klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
@@ -0,0 +1,287 @@
+package com.klp.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.klp.domain.vo.WmsCustomerVo;
+import com.klp.domain.vo.WmsExpressVo;
+import com.sf.fop.sxjd.oms.open.platform.*;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SX_EWB_ORDER_SAVE.EwbOrderSaveRequest;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SX_EWB_ORDER_SAVE.EwbOrderSaveResponse;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SX_ORDER_STATUS_NOTIFY.OrderStatusNotifyRequest;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SX_QUERY_TRACK.QueryTrackRequest;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SX_QUERY_TRACK.QueryTrackResponse;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SdkReceiveRequest;
+import com.sf.fop.sxjd.oms.open.platform.api.bean.SendResponse;
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.Date;
+import java.util.logging.Level;
+
+/**
+ * 顺心捷达路由查询工具类
+ *
+ * @author ruoyi
+ */
+public class SxjdRouteQueryUtil {
+
+ private static final ClientAccount clientAccount;
+ private static final SdkClient sdkClient;
+ private static final OpenPlatformLogger logger;
+ private static final SxOrderStatusNotifyListener sxOrderStatusNotifyListener = new SxOrderStatusNotifyListener();
+
+ // 应用信息
+ private static final String APP_KEY = "3587488e38f3ebc6334d285cce34d979";
+ private static final String APP_SECRET = "b1f971b834a6db28f71310862dd3af83";
+ private static final String APP_CODE = "000469";
+ private static final String SX_CUSTOMER_CODE = "C20002014"; // 测试联调环境
+ private static final String REQUEST_URL = "https://oms.sit.sf-express.com:9010/api/gateway/service";
+
+ static {
+ // 初始化客户端账户信息
+ clientAccount = new ClientAccount();
+ clientAccount.setAppKey(APP_KEY);
+ clientAccount.setAppCode(APP_CODE);
+ clientAccount.setAppSecret(APP_SECRET);
+ clientAccount.setSxCustomerCode(SX_CUSTOMER_CODE);
+ clientAccount.setRequestUrl(REQUEST_URL);
+
+ // 初始化SDK客户端
+ sdkClient = new SdkClient(clientAccount);
+
+ // 注册监听器
+ sdkClient.registerReceiveListener(OpenApiType.SX_ORDER_STATUS_NOTIFY, sxOrderStatusNotifyListener);
+
+ // 设置日志级别
+ logger = sdkClient.getLogger();
+ logger.setLoggerLevel(Level.ALL);
+ }
+
+ /**
+ * 创建电子运单
+ *
+ * @param request 电子运单请求对象
+ * @return 电子运单响应
+ */
+ public static SendResponse createEwbOrder(EwbOrderSaveRequest request) {
+ SendResponse sendResponse = sdkClient.send(OpenApiType.SX_EWB_ORDER_SAVE, request, EwbOrderSaveResponse.class);
+ logger.info("下单返回参数=" + JSON.toJSONString(sendResponse));
+ return sendResponse;
+ }
+
+ /**
+ * 创建电子运单(使用JSON字符串)
+ *
+ * @param requestStr JSON格式的请求字符串
+ * @return 电子运单响应
+ */
+ public static SendResponse createEwbOrderByJson(String requestStr) {
+ EwbOrderSaveRequest ewbOrderSaveRequest = JSON.parseObject(requestStr, EwbOrderSaveRequest.class);
+ return createEwbOrder(ewbOrderSaveRequest);
+ }
+
+ /**
+ * 查询货物轨迹(与其他快递工具类接口保持一致)
+ *
+ * @param expressCode 运单号
+ * @return 查询结果JSON字符串
+ */
+ public static String queryRoute(String expressCode) {
+ return queryTrackByHttp(expressCode);
+ }
+
+ /**
+ * 查询货物轨迹
+ *
+ * @param waybillId 运单号
+ * @return 查询结果
+ */
+ public static SendResponse queryTrack(String waybillId) {
+ QueryTrackRequest request = new QueryTrackRequest();
+ request.setWaybillId(waybillId);
+ SendResponse response = sdkClient.send(OpenApiType.SX_QUERY_TRACK, request, QueryTrackResponse.class);
+ logger.info("轨迹查询返回参数=" + JSON.toJSONString(response));
+ return response;
+ }
+
+ /**
+ * 解析顺心捷达返回数据,转为WmsExpressVo
+ *
+ * @param result 查询结果JSON字符串
+ * @return WmsExpressVo对象
+ */
+ public static WmsExpressVo parseData(String result) {
+ if (result == null || result.trim().isEmpty()) {
+ return null;
+ }
+
+ try {
+ JSONObject json = JSON.parseObject(result);
+ if (!json.getBooleanValue("success")) {
+ return null;
+ }
+
+ JSONObject data = json.getJSONObject("data");
+ if (data == null) {
+ return null;
+ }
+
+ JSONArray trackInfoList = data.getJSONArray("trackInfoList");
+ if (trackInfoList == null || trackInfoList.isEmpty()) {
+ return null;
+ }
+
+ // 获取最新的一条轨迹记录
+ JSONObject lastTrack = trackInfoList.getJSONObject(0);
+
+ WmsExpressVo vo = new WmsExpressVo();
+ vo.setExpressCode(lastTrack.getString("waybillId"));
+
+ // 设置时间
+ Long opTime = lastTrack.getLong("operationTime");
+ if (opTime != null) {
+ vo.setLastUpdateTime(new Date(opTime));
+ vo.setAcceptTime(new Date(opTime));
+ }
+
+ // 设置状态
+ String step = lastTrack.getString("step");
+ String trackDesc = lastTrack.getString("trackDesc");
+ vo.setLastStatus(trackDesc);
+ vo.setFirstStatusName(step);
+
+ return vo;
+ } catch (Exception e) {
+ logger.info("解析顺心捷达轨迹数据异常: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ /**
+ * 使用HTTP方式查询货物轨迹
+ *
+ * @param waybillId 运单号
+ * @return 查询结果JSON字符串
+ */
+ public static String queryTrackByHttp(String waybillId) {
+ try {
+ // 构建请求数据
+ String data = "{\"waybillId\":\"" + waybillId + "\"}";
+ String timestamp = System.currentTimeMillis() + "";
+ String dataDigest = md5Encode(data + timestamp + APP_SECRET);
+
+ // 构建请求体
+ StringBuilder body = new StringBuilder();
+ body.append("apiType=SX_QUERY_TRACK");
+ body.append("&appKey=").append(APP_KEY);
+ body.append("&sxCustomerCode=").append(SX_CUSTOMER_CODE);
+ body.append("×tamp=").append(timestamp);
+ body.append("&dataDigest=").append(dataDigest);
+ body.append("&data=").append(data);
+
+ // 发送请求
+ URL url = new URL(REQUEST_URL);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ conn.setUseCaches(false);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+ // 写入请求体
+ OutputStream out = conn.getOutputStream();
+ out.write(body.toString().getBytes(StandardCharsets.UTF_8));
+ out.flush();
+ out.close();
+
+ // 处理响应
+ StringBuilder sbResult = new StringBuilder();
+ if (200 == conn.getResponseCode()) {
+ BufferedReader responseReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+ String readLine;
+ while ((readLine = responseReader.readLine()) != null) {
+ sbResult.append(readLine).append("\n");
+ }
+ responseReader.close();
+ String result = sbResult.toString();
+ logger.info("HTTP轨迹查询返回参数=" + result);
+ return result;
+ }
+ } catch (IOException e) {
+ logger.info("HTTP轨迹查询异常: " + e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * MD5加密并Base64编码
+ *
+ * @param str 待加密字符串
+ * @return 加密后的字符串
+ */
+ public static String md5Encode(String str) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(str.getBytes(StandardCharsets.UTF_8));
+ byte[] digest = md.digest();
+ return new String(Base64.encodeBase64URLSafe(digest), StandardCharsets.UTF_8);
+ } catch (Exception e) {
+ logger.setLogEnable(("MD5加密异常: " + e.getMessage()).isEmpty());
+ }
+ return null;
+ }
+
+
+ /**
+ * 顺心订单状态通知监听器
+ */
+ public static class SxOrderStatusNotifyListener implements ReceiveListener {
+
+ @Override
+ public OpenApiType getApiType() {
+ return OpenApiType.SX_ORDER_STATUS_NOTIFY;
+ }
+
+ @Override
+ public Void execute(SdkReceiveRequest sdkReceiveRequest) throws OpenPlatformException {
+ OrderStatusNotifyRequest request = sdkReceiveRequest.getRequestData();
+ String print = JSON.toJSONString(request);
+ logger.info("接收参数={}" + print);
+ return null;
+ }
+ }
+
+ /**
+ * 测试方法
+ */
+ public static void main(String[] args) {
+ try {
+ String data = "{ \"customerOrderNo\":\"QW2315464601\", \"orderChannelNo\":\"SE1231322\", \"orderType\":1,\"whetherEwb\":true,\"senderCompany\":\"测试公司890\", \"senderName\":\"测试收\", \"senderMobile\":\"12345667634\", \"senderTel\":\"0755-8658521\", \"senderProv\":\"广东省\", \"senderCity\":\"广州市\", \"senderArea\":\"越秀区\", \"senderAddress\":\"白云街道102号筒子巷\", \"receiverCompany\":\"绿色公司\", \"receiverName\":\"大师傅\", \"receiverTel\":\"021-85685452\", \"receiverMobile\":\"12313213213\", \"receiverProv\":\"广东省\", \"receiverCity\":\"广州市\", \"receiverArea\":\"海珠区\", \"receiverAddress\":\"华洲街道\", \"cargoName\":\"装修物品\", \"totalPackages\":3, \"totalWeight\":12, \"totalVolume\":15, \"pickupWay\":\"送货(不含上楼)\", \"backSignBill\":\"电子回单\", \"remark\":\"客户接入:sxCustomerCode必填\", \"insuranceValue\":800, \"codAmount\":1024, \"fcodAmount\":620, \"getGoodMode\":\"上门接货\", \"orderSource\":\"PDD\",\"productName\":\"顺心包裹\",\"payType\":\"现付\",\"subMailNos\":\"20220426013,20220426014,20220426015\"}";
+ SendResponse response = createEwbOrderByJson(data);
+ System.out.println("下单测试结果: " + JSON.toJSONString(response));
+
+ // 测试轨迹查询
+ String waybillId = "S60201493742";
+ String trackResult = queryTrackByHttp(waybillId);
+ System.out.println("轨迹查询测试结果: " + trackResult);
+
+ // 测试MD5加密
+ String timestamp = System.currentTimeMillis() + "";
+ String appSecret = "b1f971b834a6db28f71310862dd3af83";
+ String dataDigest = md5Encode(data + timestamp + appSecret);
+ System.out.println("MD5加密结果: " + dataDigest);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}