feat(klp-wms): 添加顺心捷达快递轨迹查询功能- 新增 SxjdRouteQueryUtil 工具类,实现顺心捷达快递的电子运单创建和轨迹查询
- 在 WmsExpressServiceImpl 中集成顺心捷达的轨迹查询功能 - 添加 jd-sdk 依赖,用于顺心捷达快递的相关操作
This commit is contained in:
@@ -56,5 +56,11 @@
|
||||
<artifactId>kfpt-sdk</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jd</groupId>
|
||||
<artifactId>jd-sdk</artifactId>
|
||||
<version>1.2.89</version>
|
||||
<classifier>RELEASE</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -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);;
|
||||
}
|
||||
|
||||
287
klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
Normal file
287
klp-wms/src/main/java/com/klp/utils/SxjdRouteQueryUtil.java
Normal file
@@ -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<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("×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<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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user