From a9b0d07b8d54c1df66d45f54aeb7e35127651ddc Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sat, 7 Jun 2025 00:59:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=8F=91=E8=B4=A7=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AF=B9=E6=8E=A5=EF=BC=8C=E9=80=BB=E8=BE=91=E7=BC=96?= =?UTF-8?q?=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ShopOrderLogisticsService.java | 8 ++ .../impl/ShopOrderLogisticsServiceImpl.java | 24 +++++ .../service/WxOrderShippingService.java | 4 +- .../impl/WxOrderShippingServiceImpl.java | 95 +++++++++---------- 4 files changed, 78 insertions(+), 53 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderLogisticsService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderLogisticsService.java index 01bc4ca2..bd609f67 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderLogisticsService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderLogisticsService.java @@ -19,4 +19,12 @@ public interface ShopOrderLogisticsService extends IBaseService queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_id", orderId); + + List logisticsList = list(queryWrapper); + if (CollUtil.isEmpty(logisticsList)) { + return null; + } + + return logisticsList.get(0); + } + /** * 检测订单是否完全发货完毕 * 1.检测订单状态处于出库审核完毕 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java index 2f06d6b0..76db7a99 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxOrderShippingService.java @@ -18,11 +18,9 @@ public interface WxOrderShippingService { * * @param logisticsType 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提 * @param orderId 订单ID - * @param expressNo 快递公司编号 - * @param trackingNo 物流单号 * @return 返回上传结果,包含成功状态和错误消息 */ - Pair uploadShippingInfoToWx(Integer logisticsType, String orderId, String expressNo, String trackingNo); + Pair uploadShippingInfoToWx(Integer logisticsType, String orderId); /** * 通知微信用户确认收货 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java index bc59fd0a..f37418b7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxOrderShippingServiceImpl.java @@ -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 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 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()); } }