Files
klp-oa/klp-wms/src/main/java/com/klp/utils/StoRouteQueryUtil.java
Joshi 1cd1699bf3 feat(wms): 添加物流预览和快递问题相关功能
- 新增物流预览和快递问题相关的实体类、Mapper、Service和Controller
- 实现物流预览列表查询、导出、详情获取、新增、修改和删除功能
- 实现快递问题列表查询、详情获取、新增、修改和删除功能
- 添加百世、顺丰、申通快递的路由查询工具类
- 更新pom.xml,添加fastjson2等依赖
- 修改application-stage.yml,禁用xxl-job
2025-08-11 18:06:37 +08:00

148 lines
5.8 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.WmsExpressVo;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class StoRouteQueryUtil {
// 请填写你自己的key/secret
private static final String APP_KEY = "CAKDSqybdwbzlUC";
private static final String APP_SECRET = "wGRMVXwIf8sp4m4W6tWJcOaDfY7EPblQ";
private static final String FROM_CODE = "CAKDSqybdwbzlUC"; // 你的from_code
private static final String API_URL = "https://cloudinter-linkgateway.sto.cn/gateway/link.do";
// 申通签名算法 body+appSecretMD5后Base64
public static String sign(String body, String secret) {
String text = body + secret;
byte[] md5 = DigestUtils.md5(text);
return Base64.encodeBase64String(md5);
}
/**
* 查询申通轨迹,支持批量单号
* @param waybillNos 运单号集合
* @return 查询结果JSON
*/
public static String queryRoute(List<String> waybillNos) {
try {
// 构造content参数
JSONObject content = new JSONObject();
content.put("order", "asc");
JSONArray waybillNoList = new JSONArray();
for (String no : waybillNos) waybillNoList.add(no);
content.put("waybillNoList", waybillNoList);
String contentStr = content.toJSONString();
// 构造表单参数字符串
StringBuilder form = new StringBuilder();
form.append("api_name=STO_TRACE_QUERY_COMMON");
form.append("&content=").append(URLEncoder.encode(contentStr, "UTF-8"));
form.append("&from_appkey=").append(APP_KEY);
form.append("&from_code=").append(APP_KEY);
form.append("&to_appkey=sto_trace_query");
form.append("&to_code=sto_trace_query");
form.append("&data_digest=").append(URLEncoder.encode(sign(contentStr, APP_SECRET), "UTF-8"));
System.out.println("申通表单请求体:" + form);
URL url = new URL(API_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;charset=UTF-8");
OutputStream out = conn.getOutputStream();
out.write(form.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(), "UTF-8"));
String readLine;
while ((readLine = responseReader.readLine()) != null) {
sbResult.append(readLine).append("\n");
}
responseReader.close();
}
return sbResult.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解析申通返回数据转为WmsExpressVo列表
*/
public static WmsExpressVo parseData(String result) {
if (result == null || result.trim().isEmpty()) {
return null;
}
// 新增如果返回是XML直接打印并返回null
if (result.trim().startsWith("<")) {
System.err.println("申通返回XML错误" + result);
return null;
}
try {
JSONObject json = JSON.parseObject(result);
JSONObject data = json.getJSONObject("data");
if (data == null) return null;
for (String waybillNo : data.keySet()) {
JSONArray arr = data.getJSONArray(waybillNo);
if (arr == null || arr.isEmpty()) continue;
JSONObject last = arr.getJSONObject(arr.size() - 1);
WmsExpressVo vo = new WmsExpressVo();
vo.setExpressCode(last.getString("waybillNo"));
// 设置时间
String opTime = last.getString("opTime");
if (opTime != null) {
try {
// 解析时间格式 "2025-07-27 13:01:00"
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
vo.setAcceptTime(sdf.parse(opTime));
} catch (Exception e) {
vo.setAcceptTime(null);
}
}
// 设置状态 - 使用scanType作为状态
vo.setFirstStatusName(last.getString("memo"));
// 设置备注 - 使用memo作为备注
vo.setRemark(last.getString("scanType"));
return vo;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// main方法测试
public static void main(String[] args) {
List<String> waybillNos = new ArrayList<>();
waybillNos.add("777329412312954"); // 测试单号
String result = queryRoute(waybillNos);
System.out.println("申通原始返回:" + result);
WmsExpressVo vo = parseData(result);
if (vo != null) {
System.out.println("解析后:" + vo);
} else {
System.out.println("未解析到数据");
}
}
}