微信发货接口对接,逻辑编写
This commit is contained in:
parent
328fa9d802
commit
a9b0d07b8d
@ -19,4 +19,12 @@ public interface ShopOrderLogisticsService extends IBaseService<ShopOrderLogisti
|
||||
|
||||
CommonResult saveOrderLogistics(ShopOrderLogistics orderLogistics, Integer ss_id);
|
||||
|
||||
/**
|
||||
* 根据订单Id获取订单物流信息
|
||||
*
|
||||
* @param orderId
|
||||
* @return
|
||||
*/
|
||||
ShopOrderLogistics getShopOrderLogistics(String orderId);
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package com.suisung.mall.shop.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.api.ResultCode;
|
||||
@ -251,6 +253,28 @@ public class ShopOrderLogisticsServiceImpl extends BaseServiceImpl<ShopOrderLogi
|
||||
return CommonResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单Id获取订单物流信息
|
||||
*
|
||||
* @param orderId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ShopOrderLogistics getShopOrderLogistics(String orderId) {
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
return null;
|
||||
}
|
||||
QueryWrapper<ShopOrderLogistics> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("order_id", orderId);
|
||||
|
||||
List<ShopOrderLogistics> logisticsList = list(queryWrapper);
|
||||
if (CollUtil.isEmpty(logisticsList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return logisticsList.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测订单是否完全发货完毕
|
||||
* 1.检测订单状态处于出库审核完毕
|
||||
|
||||
@ -18,11 +18,9 @@ public interface WxOrderShippingService {
|
||||
*
|
||||
* @param logisticsType 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
|
||||
* @param orderId 订单ID
|
||||
* @param expressNo 快递公司编号
|
||||
* @param trackingNo 物流单号
|
||||
* @return 返回上传结果,包含成功状态和错误消息
|
||||
*/
|
||||
Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId, String expressNo, String trackingNo);
|
||||
Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId);
|
||||
|
||||
/**
|
||||
* 通知微信用户确认收货
|
||||
|
||||
@ -12,12 +12,14 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderLogistics;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreSfOrder;
|
||||
import com.suisung.mall.common.pojo.dto.WxOrderBaseInfoDTO;
|
||||
import com.suisung.mall.common.utils.DateTimeUtils;
|
||||
import com.suisung.mall.common.utils.RestTemplateHttpUtil;
|
||||
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderLogisticsService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreSfOrderService;
|
||||
import com.suisung.mall.shop.wechat.service.WxOrderShippingService;
|
||||
import com.suisung.mall.shop.wechat.utils.WxUtil;
|
||||
@ -47,26 +49,23 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
@Autowired
|
||||
private ShopStoreSfOrderService shopStoreSfOrderService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderLogisticsService shopOrderLogisticsService;
|
||||
|
||||
/**
|
||||
* 上传发货信息到微信
|
||||
* 参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
|
||||
*
|
||||
* @param logisticsType 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
|
||||
* @param orderId 订单ID
|
||||
* @param expressNo 快递公司编号
|
||||
* @param trackingNo 物流单号
|
||||
* @return 返回上传结果,包含成功状态和错误消息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId, String expressNo, String trackingNo) {
|
||||
final String PARAMETER_ERROR = "必要参数不能为空";
|
||||
final String ACCESS_TOKEN_ERROR = "获取AccessToken失败";
|
||||
final String ORDER_RECORD_ERROR = "无法获取订单记录";
|
||||
final String SHIPPING_INFO_ERROR = "发货信息录入失败";
|
||||
|
||||
if (StringUtils.isAnyBlank(orderId, expressNo, trackingNo)) {
|
||||
log.error(PARAMETER_ERROR);
|
||||
return Pair.of(false, PARAMETER_ERROR);
|
||||
public Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId) {
|
||||
if (StringUtils.isBlank(orderId)) {
|
||||
log.error("缺少订单Id");
|
||||
return Pair.of(false, "缺少订单Id");
|
||||
}
|
||||
|
||||
if (logisticsType == null || logisticsType < 1 || logisticsType > 4) {
|
||||
@ -75,57 +74,55 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
}
|
||||
|
||||
try {
|
||||
// Step 1: Get access token
|
||||
String accessToken = wxUtil.getAccessToken();
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
log.error("{},订单ID: {}", ACCESS_TOKEN_ERROR, orderId);
|
||||
return Pair.of(false, ACCESS_TOKEN_ERROR);
|
||||
log.error("获取AccessToken失败,订单ID: {}", orderId);
|
||||
return Pair.of(false, "获取AccessToken失败");
|
||||
}
|
||||
|
||||
// Step 2: Get order base info
|
||||
WxOrderBaseInfoDTO orderBaseInfo = shopOrderBaseService.getWxOrderBaseInfo(orderId);
|
||||
if (orderBaseInfo == null) {
|
||||
log.error("{},订单ID: {}", ORDER_RECORD_ERROR, orderId);
|
||||
return Pair.of(false, ORDER_RECORD_ERROR);
|
||||
if (orderBaseInfo == null || StrUtil.isBlank(orderBaseInfo.getDa_mobile())) {
|
||||
log.error("无法获取订单记录,订单ID: {}", orderId);
|
||||
return Pair.of(false, "无法获取订单记录");
|
||||
}
|
||||
|
||||
|
||||
//shop_order_logistics shop_store_sf_order
|
||||
// Step 3: Prepare shipping item
|
||||
JSONObject shippingItem = new JSONObject();
|
||||
shippingItem.set("item_desc", orderBaseInfo.getSubject()); // 必填项
|
||||
shippingItem.set("item_desc", orderBaseInfo.getSubject());
|
||||
|
||||
String receiverContact;
|
||||
try {
|
||||
receiverContact = CommonConstant.IDD_ZH_CN + "-" + PhoneNumberUtils.maskPhoneNumber(orderBaseInfo.getDa_mobile());
|
||||
} catch (Exception e) {
|
||||
log.warn("手机号脱敏失败,订单ID: {}, 错误信息: {}", orderId, e.getMessage());
|
||||
receiverContact = CommonConstant.IDD_ZH_CN + "-" + orderBaseInfo.getDa_mobile();
|
||||
}
|
||||
|
||||
String trackingId = "";
|
||||
String expressCompany = "";
|
||||
String receiverMobile = "";
|
||||
if (logisticsType == 1) {
|
||||
// 实体物流配送
|
||||
shippingItem.set("shipping_type", 2);
|
||||
shippingItem.set("shipping_id", orderBaseInfo.getLkl_merchant_no());
|
||||
ShopOrderLogistics shopOrderLogistics = shopOrderLogisticsService.getShopOrderLogistics(orderId);
|
||||
if (shopOrderLogistics == null) {
|
||||
log.error("无法获取快递信息,订单ID: {}", orderId);
|
||||
return Pair.of(false, "无法获取快递信息");
|
||||
}
|
||||
shippingItem.set("tracking_no", shopOrderLogistics.getOrder_tracking_number());
|
||||
shippingItem.set("express_company", shopOrderLogistics.getLogistics_number());
|
||||
shippingItem.set("contact.receiver_contact", receiverContact);
|
||||
} else if (logisticsType == 2) {
|
||||
// 同城配送(顺丰同城)
|
||||
ShopStoreSfOrder shopStoreSfOrder = shopStoreSfOrderService.getBySfOrderId(orderId);
|
||||
if (shopStoreSfOrder == null) {
|
||||
log.error("无法获取顺丰同城订单记录,订单ID: {}", orderId);
|
||||
return Pair.of(false, "无法获取顺丰同城订单记录");
|
||||
}
|
||||
|
||||
trackingId = shopStoreSfOrder.getSf_bill_id();
|
||||
expressCompany = "SF"; // 顺丰同城的快递公司代码
|
||||
receiverMobile = "";
|
||||
} else if (logisticsType == 3) {
|
||||
// 虚拟商品
|
||||
shippingItem.set("shipping_type", 4);
|
||||
} else {
|
||||
// 用户自提
|
||||
shippingItem.set("shipping_type", 1);
|
||||
shippingItem.set("tracking_no", shopStoreSfOrder.getSf_bill_id());
|
||||
shippingItem.set("express_company", "SF");
|
||||
shippingItem.set("contact.receiver_contact", receiverContact);
|
||||
}
|
||||
|
||||
// 发物流快递的必填字段
|
||||
shippingItem.set("tracking_no", trackingId);
|
||||
shippingItem.set("express_company", expressCompany);
|
||||
shippingItem.set("contact.receiver_contact", CommonConstant.IDD_ZH_CN + "-" + PhoneNumberUtils.maskPhoneNumber("13128998786"));
|
||||
|
||||
// Step 4: Prepare request payload
|
||||
JSONArray shippingList = new JSONArray().put(shippingItem);
|
||||
|
||||
JSONObject paramsJSON = new JSONObject()
|
||||
.set("order_key.order_number_type", 2)
|
||||
.set("order_key.transaction_id", orderBaseInfo.getTransaction_id())
|
||||
@ -135,21 +132,22 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
.set("upload_time", DateTimeUtils.formatDateTimeRFC3339(new Date()))
|
||||
.set("payer.openid", orderBaseInfo.getOpenid());
|
||||
|
||||
// Step 5: Send request to WeChat API
|
||||
JSONObject respObj = RestTemplateHttpUtil.sendPost(
|
||||
"https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken,
|
||||
null, paramsJSON, JSONObject.class
|
||||
);
|
||||
|
||||
if (respObj == null) {
|
||||
log.error("{},订单ID: {}, 返回结果为空", SHIPPING_INFO_ERROR, orderId);
|
||||
return Pair.of(false, SHIPPING_INFO_ERROR + ",返回结果为空");
|
||||
log.error("发货信息录入失败,订单ID: {}, 返回结果为空", orderId);
|
||||
return Pair.of(false, "发货信息录入失败,返回结果为空");
|
||||
}
|
||||
|
||||
int errCode = respObj.getInt("errcode", -1);
|
||||
if (errCode != 0) {
|
||||
String errorMsg = respObj.getStr("errmsg", "未知错误");
|
||||
log.error("{},订单ID: {}, 错误码: {}, 错误信息: {}", SHIPPING_INFO_ERROR, orderId, errCode, errorMsg);
|
||||
return Pair.of(false, SHIPPING_INFO_ERROR + ": " + errorMsg);
|
||||
log.error("发货信息录入失败,订单ID: {}, 错误码: {}, 错误信息: {}", orderId, errCode, errorMsg);
|
||||
return Pair.of(false, "发货信息录入失败: " + errorMsg);
|
||||
}
|
||||
|
||||
log.info("发货信息录入成功, 订单ID: {}", orderId);
|
||||
@ -158,12 +156,9 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
|
||||
} catch (HttpClientErrorException e) {
|
||||
log.error("HTTP请求错误,订单ID: {}, 状态码: {}, 错误信息: {}", orderId, e.getStatusCode(), e.getMessage(), e);
|
||||
return Pair.of(false, "HTTP请求错误: " + e.getMessage());
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.error("参数错误,订单ID: {}, 错误信息: {}", orderId, e.getMessage(), e);
|
||||
return Pair.of(false, "参数错误: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("{},订单ID: {}, 错误信息: {}", SHIPPING_INFO_ERROR, orderId, e.getMessage(), e);
|
||||
return Pair.of(false, SHIPPING_INFO_ERROR + ": " + e.getMessage());
|
||||
log.error("发货信息录入失败,订单ID: {}, 错误信息: {}", orderId, e.getMessage(), e);
|
||||
return Pair.of(false, "发货信息录入失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user