支付
This commit is contained in:
35
zhwl-business/zhwl-express/pom.xml
Normal file
35
zhwl-business/zhwl-express/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.zhwl</groupId>
|
||||
<artifactId>zhwl-business</artifactId>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>zhwl-express</artifactId>
|
||||
<description>快递模块</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zhwl</groupId>
|
||||
<artifactId>zhwl-system</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,33 @@
|
||||
package com.zhwl.express.api;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.zhwl.express.constants.ApiInfoConstant;
|
||||
import com.zhwl.express.core.BaseClient;
|
||||
import com.zhwl.express.pojo.HttpResult;
|
||||
import com.zhwl.express.request.BaseRequest;
|
||||
import com.zhwl.express.request.QueryTrackReq;
|
||||
import com.zhwl.express.response.QueryTrackResp;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* 实时查询
|
||||
*
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:27
|
||||
*/
|
||||
public class QueryTrack extends BaseClient {
|
||||
|
||||
public String getApiUrl(BaseRequest request) {
|
||||
return ApiInfoConstant.QUERY_URL;
|
||||
}
|
||||
|
||||
public QueryTrackResp queryTrack(QueryTrackReq queryTrackReq) throws Exception {
|
||||
HttpResult httpResult = execute(queryTrackReq);
|
||||
if (httpResult.getStatus() == HttpStatus.SC_OK && StringUtils.isNotBlank(httpResult.getBody())) {
|
||||
return new Gson().fromJson(httpResult.getBody(), QueryTrackResp.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,220 @@
|
||||
package com.zhwl.express.constants;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-15 17:43
|
||||
*/
|
||||
public class ApiInfoConstant {
|
||||
/**
|
||||
* 查询url
|
||||
*/
|
||||
public static final String QUERY_URL = "https://poll.kuaidi100.com/poll/query.do";
|
||||
/**
|
||||
* 快递查询地图轨迹url
|
||||
*/
|
||||
public static final String QUERY_MAP_VIEW_URL = "https://poll.kuaidi100.com/poll/maptrack.do";
|
||||
/**
|
||||
* 订阅url
|
||||
*/
|
||||
public static final String SUBSCRIBE_URL = "https://poll.kuaidi100.com/poll";
|
||||
/**
|
||||
* 订阅带地图url
|
||||
*/
|
||||
public static final String SUBSCRIBE_WITH_MAP_URL = "http://poll.kuaidi100.com/pollmap";
|
||||
/**
|
||||
* 订阅SCHEMA
|
||||
*/
|
||||
public static final String SUBSCRIBE_SCHEMA = "json";
|
||||
/**
|
||||
* 智能单号识别url
|
||||
*/
|
||||
public static final String AUTO_NUM_URL = "http://www.kuaidi100.com/autonumber/auto?num=%s&key=%s";
|
||||
/**
|
||||
* 电子面单html url
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_HTML_URL = "http://poll.kuaidi100.com/eorderapi.do";
|
||||
/**
|
||||
* 电子面单html方法
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_HTML_METHOD = "getElecOrder";
|
||||
/**
|
||||
* 电子面单获取图片 url
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_PIC_URL = "https://poll.kuaidi100.com/printapi/printtask.do";
|
||||
/**
|
||||
* 电子面单获取图片
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_PIC_METHOD = "getPrintImg";
|
||||
/**
|
||||
* 电子面单打印 url
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_PRINT_URL = "https://poll.kuaidi100.com/printapi/printtask.do";
|
||||
/**
|
||||
* 电子面单打印方法
|
||||
*/
|
||||
public static final String ELECTRONIC_ORDER_PRINT_METHOD = "eOrder";
|
||||
/**
|
||||
* 菜鸟淘宝账号授权
|
||||
*/
|
||||
public static final String AUTH_THIRD_URL = "https://poll.kuaidi100.com/printapi/authThird.do";
|
||||
/**
|
||||
* 云打印url
|
||||
*/
|
||||
public static final String CLOUD_PRINT_URL = "http://poll.kuaidi100.com/printapi/printtask.do?method=%s&t=%s&key=%s&sign=%s¶m=%s";
|
||||
/**
|
||||
* 自定义打印方法
|
||||
*/
|
||||
public static final String CLOUD_PRINT_CUSTOM_METHOD = "printOrder";
|
||||
/**
|
||||
* 附件打印方法
|
||||
*/
|
||||
public static final String CLOUD_PRINT_ATTACHMENT_METHOD = "imgOrder";
|
||||
/**
|
||||
* 复打方法
|
||||
*/
|
||||
public static final String CLOUD_PRINT_OLD_METHOD = "printOld";
|
||||
/**
|
||||
* 复打方法
|
||||
*/
|
||||
public static final String SEND_SMS_URL = "http://apisms.kuaidi100.com:9502/sms/send.do";
|
||||
/**
|
||||
* 商家寄件
|
||||
*/
|
||||
public static final String B_ORDER_URL = "https://order.kuaidi100.com/order/borderbestapi.do";
|
||||
/**
|
||||
* 商家寄件查询运力
|
||||
*/
|
||||
public static final String B_ORDER_QUERY_TRANSPORT_CAPACITY_METHOD = "querymkt";
|
||||
/**
|
||||
* 商家寄件下单
|
||||
*/
|
||||
public static final String B_ORDER_SEND_METHOD = "bOrderBest";
|
||||
/**
|
||||
* 商家寄件获取验证码
|
||||
*/
|
||||
public static final String B_ORDER_CODE_METHOD = "getCode";
|
||||
/**
|
||||
* 商家寄件取消
|
||||
*/
|
||||
public static final String B_ORDER_CANCEL_METHOD = "cancelBest";
|
||||
/**
|
||||
* 云平台通用请求url
|
||||
*/
|
||||
public static final String CLOUD_NORMAL_URL = "http://cloud.kuaidi100.com/api";
|
||||
/**
|
||||
* 第三方电商平台账号授权请求url
|
||||
*/
|
||||
public static final String THIRD_AUTH_URL = "https://poll.kuaidi100.com/printapi/authThird.do";
|
||||
/**
|
||||
* 商家寄件(官方寄件)请求url
|
||||
*/
|
||||
public static final String B_ORDER_OFFICIAL_URL = "https://poll.kuaidi100.com/order/borderapi.do";
|
||||
/**
|
||||
* 商家寄件(官方寄件)下单
|
||||
*/
|
||||
public static final String B_ORDER_OFFICIAL_ORDER_METHOD = "bOrder";
|
||||
/**
|
||||
* 商家寄件(官方寄件)取消
|
||||
*/
|
||||
public static final String B_ORDER_OFFICIAL_CANCEL_METHOD = "cancel";
|
||||
/**
|
||||
* 商家寄件(官方寄件)查询价格
|
||||
*/
|
||||
public static final String B_ORDER_OFFICIAL_PRICE_METHOD = "Price";
|
||||
/**
|
||||
* 同城配送请求url
|
||||
*/
|
||||
public static final String SAME_CITY_ORDER_URL = "https://order.kuaidi100.com/sameCity/order";
|
||||
/**
|
||||
* 同城配送授权方法
|
||||
*/
|
||||
public static final String SAME_CITY_AUTH_METHOD = "auth";
|
||||
/**
|
||||
* 同城配送下单方法
|
||||
*/
|
||||
public static final String SAME_CITY_ORDER_METHOD = "order";
|
||||
/**
|
||||
* 同城配送查询订单方法
|
||||
*/
|
||||
public static final String SAME_CITY_QUERY_METHOD = "query";
|
||||
/**
|
||||
* 同城配送取消订单方法
|
||||
*/
|
||||
public static final String SAME_CITY_CANCEL_METHOD = "cancel";
|
||||
/**
|
||||
* 取消方法
|
||||
*/
|
||||
public static final String CANCEL_METHOD = "cancel";
|
||||
/**
|
||||
* 指令打印方法
|
||||
*/
|
||||
public static final String CLOUD_PRINT_COMMAND = "printCommand";
|
||||
/**
|
||||
* 指令打印
|
||||
*/
|
||||
public static final String INTERNATIONAL_SHIPMENT_URL = "http://api.kuaidi100.com/sendAssistant/order/apiCall";
|
||||
/**
|
||||
* 订单导入授权url
|
||||
*/
|
||||
public static final String THIRD_PLATFORM_ORDER_SHOP_AUTHORIZE_url = "https://api.kuaidi100.com/ent/shop/authorize";
|
||||
/**
|
||||
* 订单导入提交订单获取任务接口
|
||||
*/
|
||||
public static final String THIRD_PLATFORM_ORDER_COMMIT_TASK = "https://api.kuaidi100.com/ent/order/task";
|
||||
/**
|
||||
* 订单导入提交订单回填单号
|
||||
*/
|
||||
public static final String THIRD_PLATFORM_ORDER_UPLOAD_NUM = "https://api.kuaidi100.com/ent/logistics/send";
|
||||
/**
|
||||
* 发货单接口url
|
||||
*/
|
||||
public static final String BILL_PARCELS_URL = "https://poll.kuaidi100.com/print/billparcels.do";
|
||||
/**
|
||||
* 发货单接口url
|
||||
*/
|
||||
public static final String BILL_PARCELS_METHOD = "billparcels";
|
||||
/**
|
||||
* 第三方平台网点&面单余额接口url
|
||||
*/
|
||||
public static final String THIRD_PLATFORM_REST = "getThirdInfo";
|
||||
/**
|
||||
* 快递面单OCR识别接口url
|
||||
*/
|
||||
public static final String ELEC_DETOCR_URL = "http://api.kuaidi100.com/elec/detocr";
|
||||
/**
|
||||
* 新版编辑器请求地址
|
||||
*/
|
||||
public static final String NEW_TEMPLATE_URL = "https://api.kuaidi100.com/label/order";
|
||||
/**
|
||||
* 下单
|
||||
*/
|
||||
public static final String ORDER = "order";
|
||||
/**
|
||||
* 自定义
|
||||
*/
|
||||
public static final String CUSTOM = "custom";
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
public static final String DETAIL = "detail";
|
||||
/**
|
||||
* C端寄件下单接口请求地址
|
||||
*/
|
||||
public static final String C_ORDER_URL = "https://order.kuaidi100.com/order/corderapi.do";
|
||||
/**
|
||||
* C端寄件下单接口方法
|
||||
*/
|
||||
public static final String C_ORDER_METHOD = "cOrder";
|
||||
/**
|
||||
* C端寄件查价接口方法
|
||||
*/
|
||||
public static final String C_ORDER_PRICE_METHOD = "price";
|
||||
/**
|
||||
* 可用性请求地址
|
||||
*/
|
||||
public static final String REACHABLE_URL = "http://api.kuaidi100.com/reachable.do";
|
||||
/**
|
||||
* 可用性方法
|
||||
*/
|
||||
public static final String REACHABLE_METHOD = "reachable";
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package com.zhwl.express.constants;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-15 17:24
|
||||
*/
|
||||
public class CompanyConstant {
|
||||
|
||||
/**
|
||||
* 顺丰
|
||||
*/
|
||||
public static final String SF = "shunfeng";
|
||||
/**
|
||||
* 圆通
|
||||
*/
|
||||
public static final String ZT = "zhongtong";
|
||||
/**
|
||||
* 中通
|
||||
*/
|
||||
public static final String YT = "yuantong";
|
||||
/**
|
||||
* 百世快递
|
||||
*/
|
||||
public static final String HT = "huitongkuaidi";
|
||||
/**
|
||||
* 申通
|
||||
*/
|
||||
public static final String ST = "shentong";
|
||||
/**
|
||||
* 韵达
|
||||
*/
|
||||
public static final String YD = "yunda";
|
||||
/**
|
||||
* EMS
|
||||
*/
|
||||
public static final String EMS = "ems";
|
||||
/**
|
||||
* 京东
|
||||
*/
|
||||
public static final String JD = "jd";
|
||||
/**
|
||||
* 宅急送
|
||||
*/
|
||||
public static final String ZJS = "zhaijisong";
|
||||
/**
|
||||
* 德邦
|
||||
*/
|
||||
public static final String DB = "debangkuaidi";
|
||||
|
||||
/**
|
||||
* 闪送
|
||||
*/
|
||||
public static final String SS = "shansong";
|
||||
/**
|
||||
* kfw
|
||||
*/
|
||||
public static final String KFW = "kfw";
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package com.zhwl.express.core;
|
||||
|
||||
|
||||
import com.zhwl.express.pojo.HttpResult;
|
||||
import com.zhwl.express.request.BaseRequest;
|
||||
import com.zhwl.express.response.BaseResponse;
|
||||
import com.zhwl.express.utils.HttpUtils;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-11-25 16:02
|
||||
*/
|
||||
public abstract class BaseClient implements IBaseClient {
|
||||
|
||||
private int connectTimeout = 3000;
|
||||
|
||||
private int socketTimeout = 3000;
|
||||
|
||||
public HttpResult execute(BaseRequest request) throws Exception {
|
||||
|
||||
return HttpUtils.doPost(getApiUrl(request), request, connectTimeout, socketTimeout);
|
||||
}
|
||||
|
||||
public BaseResponse executeToObject(BaseRequest request) throws Exception {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setTimeOut(int connectTimeout, int socketTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
public abstract String getApiUrl(BaseRequest request);
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.zhwl.express.core;
|
||||
|
||||
|
||||
import com.zhwl.express.pojo.HttpResult;
|
||||
import com.zhwl.express.request.BaseRequest;
|
||||
import com.zhwl.express.response.BaseResponse;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-11-25 16:09
|
||||
*/
|
||||
public interface IBaseClient {
|
||||
|
||||
HttpResult execute(BaseRequest request) throws Exception;
|
||||
|
||||
BaseResponse executeToObject(BaseRequest request) throws Exception;
|
||||
|
||||
void setTimeOut(int connectTimeout,int socketTimeout);
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
package com.zhwl.express.enums;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.zhwl.common.exception.ServiceException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Title: ExpressCompanyEnum
|
||||
* @Author wangtao
|
||||
* @Date 2025/4/2 11:25
|
||||
* @description:
|
||||
*/
|
||||
public enum ExpressCompanyEnum {
|
||||
|
||||
SF("shunfeng", "顺丰速运"),
|
||||
|
||||
ZT("zhongtong", "中通快递"),
|
||||
|
||||
YT("yuantong", "圆通速递"),
|
||||
|
||||
ST("shentong", "申通快递"),
|
||||
|
||||
HT("huitongkuaidi", "百世快递"),
|
||||
|
||||
TD("yunda", "韵达快递"),
|
||||
|
||||
EMS("ems", "EMS"),
|
||||
|
||||
JD("jd", "京东物流"),
|
||||
|
||||
ZJS("zhaijisong", "宅急送"),
|
||||
|
||||
DB("debangkuaidi", "德邦快递"),
|
||||
|
||||
JT("jtexpress", "极兔速递");
|
||||
|
||||
private String code;
|
||||
private String desc;
|
||||
|
||||
ExpressCompanyEnum(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public static ExpressCompanyEnum ofName(String name) {
|
||||
Optional<ExpressCompanyEnum> first = Arrays.stream(ExpressCompanyEnum.values()).filter(e -> e.getDesc().equals(name)).findFirst();
|
||||
if (first.isPresent()) {
|
||||
return first.get();
|
||||
} else {
|
||||
throw new ServiceException(StrUtil.format("不支持的快递公司【{}】", name));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package com.zhwl.express.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class HttpResult {
|
||||
/**
|
||||
* HTTP状态码
|
||||
*/
|
||||
private int status;
|
||||
/**
|
||||
* HTTP响应正文
|
||||
*/
|
||||
private String body;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
public HttpResult() {
|
||||
}
|
||||
|
||||
public HttpResult(int status, String body, String error) {
|
||||
this.status = status;
|
||||
this.body = body;
|
||||
this.error = error;
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package com.zhwl.express.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-11-25 16:12
|
||||
*/
|
||||
@Data
|
||||
public class BaseRequest {
|
||||
|
||||
private String url;
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package com.zhwl.express.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 15:58
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackParam {
|
||||
/**
|
||||
* 查询的快递公司的编码,一律用小写字母
|
||||
*/
|
||||
private String com;
|
||||
/**
|
||||
* 查询的快递单号, 单号的最大长度是32个字符
|
||||
*/
|
||||
private String num;
|
||||
/**
|
||||
* 收件人或寄件人的手机号或固话
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 出发地城市,省-市-区
|
||||
*/
|
||||
private String from;
|
||||
/**
|
||||
* 目的地城市,省-市-区
|
||||
*/
|
||||
private String to;
|
||||
/**
|
||||
* 添加此字段表示开通行政区域解析功能。0:关闭(默认),1:开通行政区域解析功能,2:开通行政解析功能并且返回出发、目的及当前城市信息
|
||||
*/
|
||||
private String resultv2 = "0";
|
||||
/**
|
||||
* 返回数据格式。0:json(默认),1:xml,2:html,3:text
|
||||
*/
|
||||
private String show = "0";
|
||||
/**
|
||||
* 返回结果排序方式。desc:降序(默认),asc:升序
|
||||
*/
|
||||
private String order = "desc";
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package com.zhwl.express.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 15:56
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackReq extends BaseRequest {
|
||||
/**
|
||||
* 我方分配给贵司的的公司编号, 点击查看账号信息
|
||||
*/
|
||||
private String customer;
|
||||
/**
|
||||
* 签名, 用于验证身份, 按param + key + customer 的顺序进行MD5加密(注意加密后字符串要转大写), 不需要“+”号
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 其他参数组合成的json对象
|
||||
*/
|
||||
private String param;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.zhwl.express.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-11-25 16:11
|
||||
*/
|
||||
@Data
|
||||
public class BaseResponse<T> {
|
||||
|
||||
private boolean result;
|
||||
|
||||
private String message;
|
||||
|
||||
private String status;
|
||||
|
||||
private T data;
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package com.zhwl.express.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:13
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackData {
|
||||
/**
|
||||
* 时间,原始格式
|
||||
*/
|
||||
private String time;
|
||||
/**
|
||||
* 物流轨迹节点内容
|
||||
*/
|
||||
private String context;
|
||||
/**
|
||||
* 格式化后时间
|
||||
*/
|
||||
private String ftime;
|
||||
/**
|
||||
* 行政区域的编码
|
||||
*/
|
||||
private String areaCode;
|
||||
/**
|
||||
* 行政区域的名称
|
||||
*/
|
||||
private String areaName;
|
||||
/**
|
||||
* 签收状态 (0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投)
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 本数据元对应的行政区域经纬度,resultv2=4或6标记后才会出现
|
||||
*/
|
||||
private String areaCenter;
|
||||
/**
|
||||
* 本数据元对应的行政区域拼音,resultv2=4或6标记后才会出现
|
||||
*/
|
||||
private String areaPinYin;
|
||||
/**
|
||||
* 状态值
|
||||
*/
|
||||
private String statusCode;
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package com.zhwl.express.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:16
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackPosition {
|
||||
|
||||
/**
|
||||
* 地址编码
|
||||
*/
|
||||
private String number;
|
||||
/**
|
||||
* 地址名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package com.zhwl.express.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:07
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackResp {
|
||||
/**
|
||||
* 消息体,请忽略
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* 快递单号
|
||||
*/
|
||||
private String nu;
|
||||
/**
|
||||
* 是否签收标记
|
||||
*/
|
||||
private String ischeck;
|
||||
/**
|
||||
* 快递公司编码,一律用小写字母
|
||||
*/
|
||||
private String com;
|
||||
/**
|
||||
* 通讯状态
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 轨迹详情数组
|
||||
*/
|
||||
private List<QueryTrackData> data;
|
||||
/**
|
||||
* 快递单当前状态,包括0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投,10待清关,11清关中,12已清关,13清关异常,14拒签 等13个状态
|
||||
*/
|
||||
private String state;
|
||||
/**
|
||||
* 快递单明细状态标记
|
||||
*/
|
||||
private String condition;
|
||||
|
||||
private QueryTrackRouteInfo routeInfo;
|
||||
/**
|
||||
* 查不到轨迹或者其他问题返回码
|
||||
*/
|
||||
private String returnCode;
|
||||
/**
|
||||
* 查不到轨迹或者其他问题返回结果
|
||||
*/
|
||||
private boolean result;
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package com.zhwl.express.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:14
|
||||
*/
|
||||
@Data
|
||||
public class QueryTrackRouteInfo {
|
||||
/**
|
||||
* 出发位置
|
||||
*/
|
||||
private QueryTrackPosition from;
|
||||
/**
|
||||
* 当前位置
|
||||
*/
|
||||
private QueryTrackPosition cur;
|
||||
/**
|
||||
* 收货地
|
||||
*/
|
||||
private QueryTrackPosition to;
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package com.zhwl.express.service;
|
||||
|
||||
import com.zhwl.express.enums.ExpressCompanyEnum;
|
||||
import com.zhwl.express.response.QueryTrackResp;
|
||||
|
||||
/**
|
||||
* @Title: ExpressService
|
||||
* @Author wangtao
|
||||
* @Date 2025/4/2 11:11
|
||||
* @description:
|
||||
*/
|
||||
public interface ExpressService {
|
||||
|
||||
/**
|
||||
* 查询快递
|
||||
*
|
||||
* @param companyEnum 快递公司
|
||||
* @param number 快递单号
|
||||
* @param phone 手机号(顺丰必填)
|
||||
* @return
|
||||
*/
|
||||
public QueryTrackResp queryExpress(ExpressCompanyEnum companyEnum, String number, String phone);
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
package com.zhwl.express.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.google.gson.Gson;
|
||||
import com.zhwl.common.constant.HttpStatus;
|
||||
import com.zhwl.common.core.redis.RedisCache;
|
||||
import com.zhwl.common.exception.ServiceException;
|
||||
import com.zhwl.express.api.QueryTrack;
|
||||
import com.zhwl.express.core.IBaseClient;
|
||||
import com.zhwl.express.enums.ExpressCompanyEnum;
|
||||
import com.zhwl.express.pojo.HttpResult;
|
||||
import com.zhwl.express.request.QueryTrackParam;
|
||||
import com.zhwl.express.request.QueryTrackReq;
|
||||
import com.zhwl.express.response.QueryTrackResp;
|
||||
import com.zhwl.express.service.ExpressService;
|
||||
import com.zhwl.system.service.ISysConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.zhwl.express.utils.SignUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Title: ExpressServiceImpl
|
||||
* @Author wangtao
|
||||
* @Date 2025/4/2 11:11
|
||||
* @description: 通过快递100查询快递
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class Express100ServiceImpl implements ExpressService {
|
||||
|
||||
private static final String EXPRESS_PREFIX = "express100:{}:{}";
|
||||
@Autowired
|
||||
private ISysConfigService sysConfigService;
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
private String key;
|
||||
private String customer;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
key = sysConfigService.selectConfigByKey("express.100.key");
|
||||
customer = sysConfigService.selectConfigByKey("express.100.customer");
|
||||
}
|
||||
|
||||
/**
|
||||
* 频繁查询可能会锁单,设置1小时缓存
|
||||
*
|
||||
* @param companyEnum 快递公司
|
||||
* @param number 快递单号
|
||||
* @param phone 手机号(顺丰必填)
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public QueryTrackResp queryExpress(ExpressCompanyEnum companyEnum, String number, String phone) {
|
||||
String redisKey = StrUtil.format(EXPRESS_PREFIX, companyEnum.getCode(), number);
|
||||
Object cacheObject = redisCache.getCacheObject(redisKey);
|
||||
if (ObjUtil.isNotNull(cacheObject)) {
|
||||
return (QueryTrackResp) cacheObject;
|
||||
}
|
||||
if (StrUtil.isBlank(key) || StrUtil.isBlank(customer)) {
|
||||
throw new ServiceException("尚未配置快递100查询key或者customer,无法查询物流信息");
|
||||
}
|
||||
QueryTrackReq queryTrackReq = new QueryTrackReq();
|
||||
QueryTrackParam queryTrackParam = new QueryTrackParam();
|
||||
queryTrackParam.setCom(companyEnum.getCode());
|
||||
queryTrackParam.setNum(number);
|
||||
queryTrackParam.setPhone(phone);
|
||||
String param = new Gson().toJson(queryTrackParam);
|
||||
queryTrackReq.setParam(param);
|
||||
queryTrackReq.setCustomer(customer);
|
||||
queryTrackReq.setSign(SignUtils.querySign(param, key, customer));
|
||||
|
||||
IBaseClient baseClient = new QueryTrack();
|
||||
try {
|
||||
log.info("快递100查询商品物流信息入参【{}】", JSON.toJSONString(queryTrackParam));
|
||||
HttpResult httpResult = baseClient.execute(queryTrackReq);
|
||||
log.info("快递100查询商品物流信息返回【{}】", JSON.toJSONString(httpResult));
|
||||
int status = httpResult.getStatus();
|
||||
if (HttpStatus.SUCCESS == status) {
|
||||
String body = httpResult.getBody();
|
||||
QueryTrackResp queryTrackResp = JSON.parseObject(body, QueryTrackResp.class);
|
||||
redisCache.setCacheObject(redisKey, queryTrackResp, 1, TimeUnit.HOURS);
|
||||
return queryTrackResp;
|
||||
} else {
|
||||
throw new ServiceException("请求快递100查询快递单状态码异常");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(StrUtil.format("请求快递100查询快递单【{}】异常【{}】", number, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
package com.zhwl.express.utils;
|
||||
|
||||
|
||||
import com.zhwl.express.pojo.HttpResult;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:59
|
||||
*/
|
||||
public class HttpUtils {
|
||||
|
||||
private final static String CHARSET_DEFAULT = "UTF-8";
|
||||
|
||||
/**
|
||||
* post请求 编码格式默认UTF-8
|
||||
*
|
||||
* @param url 请求url
|
||||
* @return
|
||||
*/
|
||||
public static HttpResult doPost(String url, Object obj, int connectTimeout, int socketTimeout) throws IOException, IllegalAccessException {
|
||||
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
|
||||
CloseableHttpResponse resp = null;
|
||||
|
||||
HttpResult result = new HttpResult();
|
||||
try {
|
||||
Map<String, String> params = ObjectToMapUtils.objectToMap(obj);
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(socketTimeout).build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
if (params != null && params.size() > 0) {
|
||||
List<NameValuePair> list = new ArrayList<NameValuePair>();
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(list, CHARSET_DEFAULT));
|
||||
}
|
||||
|
||||
resp = httpClient.execute(httpPost);
|
||||
String body = EntityUtils.toString(resp.getEntity(), CHARSET_DEFAULT);
|
||||
int statusCode = resp.getStatusLine().getStatusCode();
|
||||
result.setStatus(statusCode);
|
||||
result.setBody(body);
|
||||
} finally {
|
||||
if (null != resp) {
|
||||
resp.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求 编码格式默认UTF-8
|
||||
*
|
||||
* @param url 请求url
|
||||
* @return
|
||||
*/
|
||||
public static HttpResult doPostFile(String url, File file,int connectTimeout,int socketTimeout) throws IOException {
|
||||
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
|
||||
CloseableHttpResponse resp = null;
|
||||
|
||||
HttpResult result = new HttpResult();
|
||||
try {
|
||||
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(socketTimeout).build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
// 把文件加到HTTP的post请求中
|
||||
builder.addBinaryBody(
|
||||
"file",
|
||||
new FileInputStream(file),
|
||||
ContentType.MULTIPART_FORM_DATA,
|
||||
file.getName()
|
||||
);
|
||||
//HttpEntity
|
||||
HttpEntity entity = builder.build();
|
||||
httpPost.setEntity(entity);
|
||||
resp = httpClient.execute(httpPost);
|
||||
result.setStatus(resp.getStatusLine().getStatusCode());
|
||||
result.setBody(EntityUtils.toString(resp.getEntity(), CHARSET_DEFAULT));
|
||||
} finally {
|
||||
if (null != resp) {
|
||||
resp.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package com.zhwl.express.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-12-01 9:19
|
||||
*/
|
||||
public class ObjectToMapUtils {
|
||||
/**
|
||||
* 将Object对象里面的属性和值转化成Map对象
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static Map<String, String> objectToMap(Object obj) throws IllegalAccessException {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
List<Field> allField = getAllField(obj);
|
||||
for (Field field : allField) {
|
||||
field.setAccessible(true);
|
||||
String fieldName = field.getName();
|
||||
String fieldValue = "";
|
||||
if (field.getType() == String.class || field.getType() == Integer.class || field.getType() == int.class) {
|
||||
fieldValue = field.get(obj) == null ? "" : field.get(obj).toString();
|
||||
}
|
||||
map.put(fieldName, fieldValue);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<Field> getAllField(Object obj) {
|
||||
List<Field> fieldList = new ArrayList<Field>();
|
||||
Class<?> clazz = obj.getClass();
|
||||
while (clazz != null) {
|
||||
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
return fieldList;
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
package com.zhwl.express.utils;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
/**
|
||||
* @Author: api.kuaidi100.com
|
||||
* @Date: 2020-07-14 16:54
|
||||
*/
|
||||
public class SignUtils {
|
||||
|
||||
/**
|
||||
* 快递100加密方式统一为MD5后转大写
|
||||
*
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public static String sign(String msg) {
|
||||
return DigestUtils.md5Hex(msg).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询加密
|
||||
* @param param
|
||||
* @param key
|
||||
* @param customer
|
||||
* @return
|
||||
*/
|
||||
public static String querySign(String param,String key,String customer){
|
||||
return sign(param+key+customer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印/下单 加密
|
||||
* @param param
|
||||
* @param t
|
||||
* @param key
|
||||
* @param secret
|
||||
* @return: java.lang.String
|
||||
* @author: api.kuaidi100.com
|
||||
* @time: 2020/12/3 9:23
|
||||
*/
|
||||
public static String printSign(String param,String t,String key,String secret){
|
||||
return sign(param+t+key+secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云平台 加密
|
||||
* @param key
|
||||
* @param secret
|
||||
* @return: java.lang.String
|
||||
* @author: api.kuaidi100.com
|
||||
* @time: 2020/12/3 9:23
|
||||
*/
|
||||
public static String cloudSign(String key,String secret){
|
||||
return sign(key+secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信加密
|
||||
* @param key
|
||||
* @param userId
|
||||
* @return: java.lang.String
|
||||
* @author: api.kuaidi100.com
|
||||
* @time: 2020/12/3 9:32
|
||||
*/
|
||||
public static String smsSign(String key,String userId){
|
||||
return sign(key+userId);
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user