|
@@ -0,0 +1,226 @@
|
|
|
+package com.fjhx.kd100.util;
|
|
|
+
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.extra.spring.SpringUtil;
|
|
|
+import cn.hutool.http.HttpStatus;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.annotation.TableName;
|
|
|
+import com.fjhx.kd100.constant.Kd100Constant;
|
|
|
+import com.fjhx.kd100.constant.LogisticsConstant;
|
|
|
+import com.fjhx.kd100.entity.config.po.ConfigInfo;
|
|
|
+import com.fjhx.kd100.entity.logistics.po.LogisticsInfo;
|
|
|
+import com.fjhx.kd100.service.config.ConfigInfoService;
|
|
|
+import com.fjhx.kd100.service.logistics.LogisticsInfoService;
|
|
|
+import com.kuaidi100.sdk.api.QueryTrack;
|
|
|
+import com.kuaidi100.sdk.api.Subscribe;
|
|
|
+import com.kuaidi100.sdk.contant.ApiInfoConstant;
|
|
|
+import com.kuaidi100.sdk.core.IBaseClient;
|
|
|
+import com.kuaidi100.sdk.pojo.HttpResult;
|
|
|
+import com.kuaidi100.sdk.request.*;
|
|
|
+import com.kuaidi100.sdk.utils.SignUtils;
|
|
|
+import com.ruoyi.common.config.HxConfig;
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
|
+import com.ruoyi.common.utils.SecurityUtils;
|
|
|
+import lombok.extern.log4j.Log4j2;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+import java.lang.annotation.Annotation;
|
|
|
+import java.net.URLDecoder;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+@Log4j2
|
|
|
+public class KD100Util {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 实时快递查询接口
|
|
|
+ *
|
|
|
+ * @param com 快递公司编码
|
|
|
+ * @param num 快递单号
|
|
|
+ */
|
|
|
+ public static KD100Result queryTrack(String com, String num) {
|
|
|
+ HttpResult httpResult;
|
|
|
+
|
|
|
+ ConfigInfo configInfo = getConfigInfo();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 参数组合成的json对象
|
|
|
+ QueryTrackParam queryTrackParam = new QueryTrackParam();
|
|
|
+ queryTrackParam.setCom(com);
|
|
|
+ queryTrackParam.setNum(num);
|
|
|
+ String param = JSON.toJSONString(queryTrackParam);
|
|
|
+
|
|
|
+ // 快递100入参
|
|
|
+ QueryTrackReq queryTrackReq = new QueryTrackReq();
|
|
|
+ queryTrackReq.setParam(param);
|
|
|
+ queryTrackReq.setCustomer(configInfo.getKdCustomer());
|
|
|
+ queryTrackReq.setSign(SignUtils.querySign(param, configInfo.getKdKey(), configInfo.getKdCustomer()));
|
|
|
+
|
|
|
+ // 查询快递100
|
|
|
+ httpResult = new QueryTrack().execute(queryTrackReq);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("请求kd100发生异常", e);
|
|
|
+ throw new ServiceException("请求kd100发生异常,异常原因:" + e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Objects.equals(httpResult.getStatus(), HttpStatus.HTTP_OK)) {
|
|
|
+ return JSON.parseObject(httpResult.getBody()).toJavaObject(KD100Result.class);
|
|
|
+ } else {
|
|
|
+ log.error("查询快递100失败,失败原因:{}", httpResult.getBody());
|
|
|
+ throw new ServiceException("查询快递100失败,失败原因:" + httpResult.getBody());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取快递状态并监听未到货快递
|
|
|
+ *
|
|
|
+ * @param com 快递公司编码
|
|
|
+ * @param num 快递单号
|
|
|
+ * @param businessId 业务id
|
|
|
+ * @param businessType 业务类型
|
|
|
+ * @param cls 数据库表映射实体
|
|
|
+ */
|
|
|
+ public static LogisticsInfo monitor(String com, String num, Long businessId, Integer businessType, Class<?> cls) {
|
|
|
+ // 查询快递100的物流信息
|
|
|
+ KD100Result result = KD100Util.queryTrack(com, num);
|
|
|
+ String message = result.getMessage();
|
|
|
+ if (Objects.equals(message, "查询无结果,请隔段时间再查")) {
|
|
|
+ return saveInfo(com, num, LogisticsConstant.KD100Status.STATUS_N, businessId, businessType, cls);
|
|
|
+ }
|
|
|
+ if (Objects.equals(message, "ok")) {
|
|
|
+ Integer state = result.getState();
|
|
|
+ if (!Objects.equals(state, LogisticsConstant.KD100Status.STATUS_3)) {
|
|
|
+ // 如果不是已签收状态,则开启订阅(物流状态跟踪并推送)
|
|
|
+ KD100Util.subscribe(com, num);
|
|
|
+ }
|
|
|
+ return saveInfo(com, num, state, businessId, businessType, cls);
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("快递100异常:" + message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存快递信息
|
|
|
+ */
|
|
|
+ private static LogisticsInfo saveInfo(String com, String num, Integer state, Long businessId, Integer businessType, Class<?> cls) {
|
|
|
+
|
|
|
+ LogisticsInfo logisticsInfo = new LogisticsInfo();
|
|
|
+ logisticsInfo.setCompany(com);
|
|
|
+ logisticsInfo.setNumber(num);
|
|
|
+ logisticsInfo.setState(state);
|
|
|
+ logisticsInfo.setBusinessId(businessId);
|
|
|
+ logisticsInfo.setBusinessType(businessType);
|
|
|
+ logisticsInfo.setTableName(getTableName(cls));
|
|
|
+
|
|
|
+ LogisticsInfoService logisticsInfoService = SpringUtil.getBean(LogisticsInfoService.class);
|
|
|
+ logisticsInfoService.save(logisticsInfo);
|
|
|
+ return logisticsInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String getTableName(Class<?> cls) {
|
|
|
+ Annotation[] annotations = cls.getAnnotations();
|
|
|
+ TableName tableName = null;
|
|
|
+ for (Annotation annotation : annotations) {
|
|
|
+ if (annotation instanceof TableName) {
|
|
|
+ tableName = (TableName) annotation;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tableName != null) {
|
|
|
+ return tableName.value();
|
|
|
+ } else {
|
|
|
+ String name = cls.getSimpleName();
|
|
|
+ return StrUtil.toUnderlineCase(name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订阅接口
|
|
|
+ *
|
|
|
+ * @param com 快递公司编码
|
|
|
+ * @param num 快递单号
|
|
|
+ */
|
|
|
+ public static void subscribe(String com, String num) {
|
|
|
+ HttpResult result;
|
|
|
+ ConfigInfo configInfo = getConfigInfo();
|
|
|
+ try {
|
|
|
+ SubscribeParameters subscribeParameters = new SubscribeParameters();
|
|
|
+ subscribeParameters.setCallbackurl(getCallbackUrl());
|
|
|
+
|
|
|
+ SubscribeParam subscribeParam = new SubscribeParam();
|
|
|
+ subscribeParam.setParameters(subscribeParameters);
|
|
|
+ subscribeParam.setCompany(com);
|
|
|
+ subscribeParam.setNumber(num);
|
|
|
+ subscribeParam.setKey(configInfo.getKdKey());
|
|
|
+
|
|
|
+ SubscribeReq subscribeReq = new SubscribeReq();
|
|
|
+ subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
|
|
|
+ subscribeReq.setParam(JSON.toJSONString(subscribeParam));
|
|
|
+
|
|
|
+ IBaseClient subscribe = new Subscribe();
|
|
|
+ result = subscribe.execute(subscribeReq);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.toString());
|
|
|
+ throw new ServiceException("请求第三方快递订阅功能异常:" + e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Objects.equals(result.getStatus(), HttpStatus.HTTP_OK)) {
|
|
|
+ JSONObject body = JSON.parseObject(result.getBody());
|
|
|
+ if (!Objects.equals(body.getBoolean("result"), Boolean.TRUE)) {
|
|
|
+ log.error("监听物流消息失败: com:{}, num:{}, message:{}", com, num, result.getBody());
|
|
|
+ throw new ServiceException("监听物流消息失败:" + result.getBody());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("监听物流消息失败:" + result.getError());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析数据:回调结果
|
|
|
+ *
|
|
|
+ * @param data 物流信息
|
|
|
+ */
|
|
|
+ public static JSONObject parseCallbackData(String data) {
|
|
|
+ log.info("快递100接口回调数据:{}", data);
|
|
|
+
|
|
|
+ if (StrUtil.isNotBlank(data) && StringUtils.indexOf(data, "param=") != -1) {
|
|
|
+ data = StringUtils.substringAfter(data, "param=");
|
|
|
+ try {
|
|
|
+ data = URLDecoder.decode(data, "UTF-8");
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new ServiceException("物流信息推送失败,参数解码异常!");
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject object = JSON.parseObject(data);
|
|
|
+ if (ObjectUtil.isNotEmpty(object) && ObjectUtil.isNotEmpty(object.getJSONObject("lastResult"))) {
|
|
|
+ JSONObject body = object.getJSONObject("lastResult");
|
|
|
+ if (ObjectUtil.isNotEmpty(body.get("message")) && StrUtil.equalsIgnoreCase(body.getString("message"), "ok")) {
|
|
|
+ return body;
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("物流信息推送失败,原因:物流信息【" + body.getString("message") + "】!");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("物流信息推送失败,参数解析异常!");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("物流信息推送失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String getCallbackUrl() {
|
|
|
+ return HxConfig.getHttpUrl() + Kd100Constant.CALLBACK_URL;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ConfigInfo getConfigInfo() {
|
|
|
+ ConfigInfoService configInfoService = SpringUtil.getBean(ConfigInfoService.class);
|
|
|
+ String tenantId = SecurityUtils.getTenantId();
|
|
|
+ ConfigInfo configInfo = configInfoService.getOne(q -> q.eq(ConfigInfo::getTenantId, tenantId));
|
|
|
+ if (configInfo == null) {
|
|
|
+ throw new ServiceException("租户未配置快递100信息");
|
|
|
+ }
|
|
|
+ return configInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|