Files
GEAR-OA/gear-oa/src/main/java/com/gear/oa/utils/StoRouteQueryUtil.java

148 lines
5.8 KiB
Java
Raw Normal View History

package com.gear.oa.utils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.gear.oa.domain.vo.OaExpressVo;
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;
}
}
/**
* 解析申通返回数据转为OaExpressVo列表
*/
public static OaExpressVo 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);
OaExpressVo vo = new OaExpressVo();
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);
OaExpressVo vo = parseData(result);
if (vo != null) {
System.out.println("解析后:" + vo);
} else {
System.out.println("未解析到数据");
}
}
}