Files
klp-oa/klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
Joshi 55acbed0cb feat(klp-wms): 添加顺心捷达快递轨迹查询功能- 新增 SxjdRouteQueryUtil 工具类,实现顺心捷达快递的电子运单创建和轨迹查询
- 在 WmsExpressServiceImpl 中集成顺心捷达的轨迹查询功能
- 添加 jd-sdk 依赖,用于顺心捷达快递的相关操作
2025-08-13 13:57:59 +08:00

288 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<EwbOrderSaveResponse> createEwbOrder(EwbOrderSaveRequest request) {
SendResponse<EwbOrderSaveResponse> 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<EwbOrderSaveResponse> 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<QueryTrackResponse> queryTrack(String waybillId) {
QueryTrackRequest request = new QueryTrackRequest();
request.setWaybillId(waybillId);
SendResponse<QueryTrackResponse> 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("&timestamp=").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<OrderStatusNotifyRequest, Void> {
@Override
public OpenApiType getApiType() {
return OpenApiType.SX_ORDER_STATUS_NOTIFY;
}
@Override
public Void execute(SdkReceiveRequest<OrderStatusNotifyRequest, Void> 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<EwbOrderSaveResponse> 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();
}
}
}