From fcfd33385330659f8d54dc26f2dcaa30c1f729e8 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Thu, 11 Sep 2025 17:00:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A1=BA=E4=B8=B0=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E8=84=9A=E6=9C=AC=E8=87=AA=E5=8A=A8=E9=80=80=E6=AC=BE?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E9=83=A8=E4=BB=BD?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E7=9A=84=E8=AE=A2=E5=8D=95=E5=85=A8=E9=A2=9D?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E5=89=A9=E4=BD=99=E7=9A=84=E6=AC=BE=E9=A1=B9?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/LakalaApiServiceImpl.java | 201 +++++++++--------- .../order/service/ShopOrderReturnService.java | 11 + .../impl/ShopOrderBaseServiceImpl.java | 6 +- .../impl/ShopOrderReturnServiceImpl.java | 180 +++++++++++++--- .../service/impl/SFExpressApiServiceImpl.java | 125 +++++++---- pom.xml | 37 ++-- 6 files changed, 371 insertions(+), 189 deletions(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index 36dfdc63..16a83c06 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java @@ -2264,120 +2264,121 @@ public class LakalaApiServiceImpl implements LakalaApiService { */ @Override public JSONObject sacsSeparateNotify(HttpServletRequest request) { - log.info("开始处理拉卡拉分账结果通知异步回调"); + log.info("[拉卡拉分账通知] 开始处理拉卡拉分账结果通知异步回调"); - // 1. 验签处理 - 验证通知来源的合法性 - log.debug("开始进行通知签名验证"); - Pair signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); - if (!signCheckResult.getFirst()) { - String errorMsg = "分账通知验签失败: " + signCheckResult.getSecond(); - log.warn(errorMsg); - return JSONUtil.createObj() - .set("code", "FAIL") - .set("retMsg", signCheckResult.getSecond()); - } - - // 2. 解析请求参数 - 将验签后的参数转换为JSON对象 - log.debug("解析通知参数"); - JSONObject paramsJson = JSONUtil.parseObj(signCheckResult.getSecond()); - if (paramsJson == null) { - String errorMsg = "分账通知参数解析失败: 请求参数为空"; - log.error(errorMsg); - return JSONUtil.createObj() - .put("code", "FAIL") - .put("message", "请求参数为空"); - } - - // 3. 提取关键参数并校验 - 确保必要参数完整 - log.debug("校验必要参数完整性"); - String logNo = paramsJson.getStr("log_no"); // 合单订单是子单流水号,非合单时是主单流水号 - String separateNo = paramsJson.getStr("separate_no"); - String outSeparateNo = paramsJson.getStr("out_separate_no"); - String status = paramsJson.getStr("status"); - String finalStatus = paramsJson.getStr("final_status"); - - - List missingParams = new ArrayList<>(); - if (StrUtil.isBlank(outSeparateNo)) missingParams.add("outSeparateNo"); - if (StrUtil.isBlank(separateNo)) missingParams.add("separateNo"); - if (StrUtil.isBlank(status)) missingParams.add("status"); - - if (!missingParams.isEmpty()) { - String errorMsg = "分账通知缺少必要参数: " + String.join(", ", missingParams); - log.error(errorMsg + ", 参数详情: {}", paramsJson); - return JSONUtil.createObj() - .put("code", "FAIL") - .put("message", errorMsg); - } - - LklOrderSeparate lklOrderSeparateExist = lklOrderSeparateService.getByLogNoAndOutTradeNo(logNo, outSeparateNo); - if (lklOrderSeparateExist == null) { - String errorMsg = "未找到对应的分账记录"; - log.error(errorMsg + ", 外部分账单号={}, 分账单号={}, 参数详情: {}", outSeparateNo, separateNo, paramsJson); - return JSONUtil.createObj() - .put("code", "FAIL") - .put("message", errorMsg); - } - - if ("SUCCESS".equals(lklOrderSeparateExist.getFinal_status())) { - String errorMsg = "分账已处理成功,请不要重复通知"; - log.warn(errorMsg + ", 订单号={}, 外部分账单号={}, 参数详情: {}", logNo, outSeparateNo, paramsJson); - return JSONUtil.createObj() - .put("code", "SUCCESS") - .put("message", "分账已处理成功,请不要重复通知"); - } - - if (!"FAIL".equals(lklOrderSeparateExist.getFinal_status())) { - String errorMsg = "已受理或处理中,成功后再通知"; - log.warn(errorMsg + ", 订单号={}, 外部分账单号={}, 参数详情: {}", logNo, outSeparateNo, paramsJson); - return JSONUtil.createObj() - .put("code", "FAIL") - .put("message", "已受理或处理中,成功后再通知"); - } - - // 4. 记录关键参数信息,便于问题排查 - log.info("接收到分账通知,分账单号={}, 外部分账单号={}, 状态={}, 最终状态={}", - separateNo, outSeparateNo, status, finalStatus); - - // 5. 构建分账记录对象 - 准备更新数据库的分账记录 - LklOrderSeparate lklOrderSeparate = new LklOrderSeparate(); - lklOrderSeparate.setLog_no(logNo); - lklOrderSeparate.setSeparate_no(separateNo); - lklOrderSeparate.setOut_separate_no(outSeparateNo); - lklOrderSeparate.setStatus(status); - lklOrderSeparate.setFinal_status(finalStatus); - lklOrderSeparate.setCal_type(paramsJson.getStr("cal_type")); - lklOrderSeparate.setSeparate_type(paramsJson.getStr("separate_type")); - lklOrderSeparate.setSeparate_date(paramsJson.getStr("separate_date")); - lklOrderSeparate.setTotal_separate_value(paramsJson.getInt("total_amt")); - lklOrderSeparate.setRemark("分账已完成"); - lklOrderSeparate.setFinish_date(paramsJson.getStr("finish_date")); - - // 处理detail_datas(避免空指针) - JSONArray detailDatas = paramsJson.getJSONArray("detail_datas"); - lklOrderSeparate.setDetail_datas(detailDatas != null ? detailDatas.toString() : "[]"); - - // 6. 持久化处理 - 更新分账记录到数据库 - log.debug("开始更新分账记录到数据库"); try { + // 1. 验签处理 - 验证通知来源的合法性 + Pair signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); + if (!signCheckResult.getFirst()) { + String errorMsg = "分账通知验签失败: " + signCheckResult.getSecond(); + log.warn("[拉卡拉分账通知] {}", errorMsg); + return JSONUtil.createObj() + .set("code", "FAIL") + .set("message", signCheckResult.getSecond()); + } + + // 2. 解析请求参数 - 将验签后的参数转换为JSON对象 + JSONObject paramsJson = JSONUtil.parseObj(signCheckResult.getSecond()); + if (paramsJson == null) { + String errorMsg = "分账通知参数解析失败: 请求参数为空"; + log.error("[拉卡拉分账通知] {}", errorMsg); + return JSONUtil.createObj() + .put("code", "FAIL") + .put("message", "请求参数为空"); + } + + // 3. 提取关键参数并校验 - 确保必要参数完整 + String logNo = paramsJson.getStr("log_no"); // 合单订单是子单流水号,非合单时是主单流水号 + String separateNo = paramsJson.getStr("separate_no"); + String outSeparateNo = paramsJson.getStr("out_separate_no"); + String status = paramsJson.getStr("status"); + String finalStatus = paramsJson.getStr("final_status"); + + List missingParams = new ArrayList<>(); + if (StrUtil.isBlank(outSeparateNo)) missingParams.add("outSeparateNo"); + if (StrUtil.isBlank(separateNo)) missingParams.add("separateNo"); + if (StrUtil.isBlank(status)) missingParams.add("status"); + + if (!missingParams.isEmpty()) { + String errorMsg = "分账通知缺少必要参数: " + String.join(", ", missingParams); + log.error("[拉卡拉分账通知] {},参数详情: {}", errorMsg, paramsJson); + return JSONUtil.createObj() + .put("code", "FAIL") + .put("message", errorMsg); + } + + // 4. 查询现有分账记录 + LklOrderSeparate lklOrderSeparateExist = lklOrderSeparateService.getByLogNoAndOutTradeNo(logNo, outSeparateNo); + if (lklOrderSeparateExist == null) { + String errorMsg = "未找到对应的分账记录"; + log.error("[拉卡拉分账通知] {},外部分账单号={},分账单号={},参数详情: {}", + errorMsg, outSeparateNo, separateNo, paramsJson); + return JSONUtil.createObj() + .put("code", "FAIL") + .put("message", errorMsg); + } + + // 5. 检查分账记录状态,避免重复处理 + String existingFinalStatus = lklOrderSeparateExist.getFinal_status(); + if ("SUCCESS".equals(existingFinalStatus)) { + String warnMsg = "分账已处理成功,请不要重复通知"; + log.warn("[拉卡拉分账通知] {},订单号={},外部分账单号={},参数详情: {}", + warnMsg, logNo, outSeparateNo, paramsJson); + return JSONUtil.createObj() + .put("code", "SUCCESS") + .put("message", "分账已处理成功,请不要重复通知"); + } + + if (!"FAIL".equals(existingFinalStatus) && StrUtil.isNotBlank(existingFinalStatus)) { + String warnMsg = "已受理或处理中,成功后再通知"; + log.warn("[拉卡拉分账通知] {},订单号={},外部分账单号={},参数详情: {}", + warnMsg, logNo, outSeparateNo, paramsJson); + return JSONUtil.createObj() + .put("code", "FAIL") + .put("message", "已受理或处理中,成功后再通知"); + } + + // 6. 记录关键参数信息,便于问题排查 + log.info("[拉卡拉分账通知] 接收到分账通知,分账单号={},外部分账单号={},状态={},最终状态={}", + separateNo, outSeparateNo, status, finalStatus); + + // 7. 构建分账记录对象 - 准备更新数据库的分账记录 + LklOrderSeparate lklOrderSeparate = new LklOrderSeparate(); + lklOrderSeparate.setLog_no(logNo); + lklOrderSeparate.setSeparate_no(separateNo); + lklOrderSeparate.setOut_separate_no(outSeparateNo); + lklOrderSeparate.setStatus(status); + lklOrderSeparate.setFinal_status(finalStatus); + lklOrderSeparate.setCal_type(paramsJson.getStr("cal_type")); + lklOrderSeparate.setSeparate_type(paramsJson.getStr("separate_type")); + lklOrderSeparate.setSeparate_date(paramsJson.getStr("separate_date")); + lklOrderSeparate.setTotal_separate_value(paramsJson.getInt("total_separate_value", 0)); + lklOrderSeparate.setRemark("分账已完成"); + lklOrderSeparate.setFinish_date(paramsJson.getStr("finish_date")); + + // 处理detail_datas(避免空指针) + JSONArray detailDatas = paramsJson.getJSONArray("detail_datas"); + lklOrderSeparate.setDetail_datas(detailDatas != null ? detailDatas.toString() : "[]"); + + // 8. 持久化处理 - 更新分账记录到数据库 boolean updateSuccess = lklOrderSeparateService.addOrUpdateByReceiverNo(lklOrderSeparate); if (!updateSuccess) { String errorMsg = String.format("分账记录更新失败, separateNo=%s", separateNo); - log.error(errorMsg); + log.error("[拉卡拉分账通知] {}", errorMsg); return JSONUtil.createObj() .put("code", "FAIL") .put("message", "数据更新失败"); } - // 7. 记录处理成功日志 - log.info("分账通知处理成功, separateNo={}, status={}", separateNo, status); + // 9. 记录处理成功日志 + log.info("[拉卡拉分账通知] 分账通知处理成功, separateNo={}, status={}", separateNo, status); return JSONUtil.createObj() .put("code", "SUCCESS") .put("message", "操作成功"); } catch (Exception e) { - // 8. 异常处理 - String errorMsg = String.format("分账通知数据处理异常, separateNo=%s: %s", separateNo, e.getMessage()); - log.error(errorMsg, e); + // 10. 异常处理 + String errorMsg = String.format("分账通知数据处理异常: %s", e.getMessage()); + log.error("[拉卡拉分账通知] {}", errorMsg, e); return JSONUtil.createObj() .put("code", "FAIL") .put("message", "系统处理异常"); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java index d3a04d56..4ae76f0f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderReturnService.java @@ -175,6 +175,17 @@ public interface ShopOrderReturnService extends IBaseService { */ CommonResult addWholeItems(String orderId, Boolean isSystemOpt, String remark); + /** + * 对已存在部分退款的订单,进行剩余商品的全部退款 + * 该方法用于处理订单中部分商品已经申请退款后,对剩余商品进行整单退款的场景 + * + * @param orderId 订单ID + * @param isSystemOpt 是否系统自动操作 + * @param remark 退单备注 + * @return CommonResult 退款申请结果 + */ + CommonResult addRemainingItems(String orderId, Boolean isSystemOpt, String remark); + /** * 退货单转单-供应商 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 47932f7e..e9f78848 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -2347,10 +2347,10 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl + * 该方法用于处理顺丰同城配送超时的情况,自动为订单创建退货申请并处理退款流程。 + * 主要包括以下几个步骤: + * 1. 创建整单退货申请 + * 2. 查询创建的退货单 + * 3. 设置退货相关信息 + * 4. 处理退货审核流程 + *

* - * @param shopOrderId

- * RETURN_PROCESS_SUBMIT = 3100; //【客户】提交退单1ReturnReturn - * RETURN_PROCESS_CHECK = 3105; //退单审核1ReturnReturn - * RETURN_PROCESS_RECEIVED = 3110; //收货确认0ReturnReturn - * RETURN_PROCESS_REFUND = 3115; //退款确认0ReturnReturn - * RETURN_PROCESS_RECEIPT_CONFIRMATION = 3120; //[【客户】收款确认0 ReturnReturn - * RETURN_PROCESS_FINISH = 3125; //完成1退货退款 - * RETURN_PROCESS_REFUSED = 3130; //-商家拒绝退货 - * RETURN_PROCESS_CANCEL = 3135; //-买家取消退款 - * @return + * @param shopOrderId 商城订单ID + * @return Boolean 处理结果,true表示成功,false表示失败 */ - @GlobalTransactional + @GlobalTransactional(timeoutMills = 30000, name = "sf-express-expired-force-refund") @Override public Boolean sfExpressExpiredForceRefund(String shopOrderId) { + logger.info("[顺丰超时自动退款] 开始处理订单: shopOrderId={}", shopOrderId); - String remark = "配送异常自动退款!"; - // 先整单退货申请 - CommonResult commonResult = addWholeItems(shopOrderId, true, remark); - commonResult.checkFenResult(); + try { + String remark = "同城配送异常自动退款!"; - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("order_id", shopOrderId); - ShopOrderReturn shopOrderReturn = findOne(queryWrapper); - if (shopOrderReturn == null) { - throw new ApiException(I18nUtil._("订单信息异常!")); + // 先整单退货申请 + CommonResult commonResult = addWholeItems(shopOrderId, true, remark); + commonResult.checkFenResult(); + logger.debug("[顺丰超时自动退款] 整单退货申请创建成功: shopOrderId={}", shopOrderId); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_id", shopOrderId); + ShopOrderReturn shopOrderReturn = findOne(queryWrapper); + + if (shopOrderReturn == null) { + logger.error("[顺丰超时自动退款] 订单信息异常,未找到退货单: shopOrderId={}", shopOrderId); + throw new ApiException(I18nUtil._("订单信息异常!")); + } + + shopOrderReturn.setReturn_flag(0); // 0-不用退货;1-需要退货 + shopOrderReturn.setReturn_buyer_message(remark); + shopOrderReturn.setReturn_store_message(remark); + logger.debug("[顺丰超时自动退款] 退货单信息设置完成: returnId={}", shopOrderReturn.getReturn_id()); + + // 退货审核(商家同意退款,仅仅退款,因为商品还没有配送出去) + Boolean result = processReviewList(shopOrderReturn, 0); + if (result) { + logger.info("[顺丰超时自动退款] 处理完成: shopOrderId={}", shopOrderId); + } else { + logger.error("[顺丰超时自动退款] 退货审核处理失败: shopOrderId={}", shopOrderId); + } + + return result; + } catch (Exception e) { + logger.error("[顺丰超时自动退款] 处理过程中发生异常: shopOrderId={}", shopOrderId, e); + throw e; } - - shopOrderReturn.setReturn_flag(0); // 0-不用退货;1-需要退货 - shopOrderReturn.setReturn_buyer_message(remark); - shopOrderReturn.setReturn_store_message(remark); - - // 退货审核(商家同意退款,仅仅退款,因为商品还没有配送出去) - return processReviewList(shopOrderReturn, 0); } /** @@ -2176,6 +2194,114 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl itemQueryWrapper = new QueryWrapper<>(); + itemQueryWrapper.eq("order_id", orderId); + List allOrderItems = shopOrderItemService.find(itemQueryWrapper); + + if (CollectionUtil.isEmpty(allOrderItems)) { + throw new ApiException(I18nUtil._("订单商品表为空!")); + } + + // 获取已申请退款的商品ID列表 + Set refundedItemIds = getRefundedItemIds(orderId); + + // 筛选出尚未申请退款的商品 + List remainingItems = allOrderItems.stream() + .filter(item -> !refundedItemIds.contains(item.getOrder_item_id())) + .collect(Collectors.toList()); + + if (CollectionUtil.isEmpty(remainingItems)) { + throw new ApiException(I18nUtil._("订单中所有商品均已申请退款!")); + } + + // 生成退款单 + OrderReturnInputVo orderReturnInputVo = new OrderReturnInputVo(); + orderReturnInputVo.setOrder_id(orderId); + orderReturnInputVo.setReturn_tel(""); + orderReturnInputVo.setReturn_buyer_message(I18nUtil._(remark)); + orderReturnInputVo.setUser_id(orderInfo.getBuyer_user_id()); + orderReturnInputVo.setSystem_opear(isSystemOpt); + + // 为剩余商品创建退款申请 + for (ShopOrderItem orderItem : remainingItems) { + OrderReturnItemInputVo returnItemInputVo = new OrderReturnItemInputVo(); + returnItemInputVo.setOrder_item_id(orderItem.getOrder_item_id()); + returnItemInputVo.setReturn_item_num(orderItem.getOrder_item_quantity()); + returnItemInputVo.setReturn_refund_amount(orderItem.getOrder_item_payment_amount()); + + orderReturnInputVo.getReturn_items().add(returnItemInputVo); + } + + return addItem(orderReturnInputVo, true); + } + + /** + * 获取订单中已申请退款的商品ID列表 + * + * @param orderId 订单ID + * @return Set 已申请退款的商品ID集合 + */ + private Set getRefundedItemIds(String orderId) { + Set refundedItemIds = new HashSet<>(); + + // 查询该订单所有未取消的退款单 + QueryWrapper returnQueryWrapper = new QueryWrapper<>(); + returnQueryWrapper.eq("order_id", orderId) + .ne("return_state_id", StateCode.RETURN_PROCESS_CANCEL); + List shopOrderReturns = find(returnQueryWrapper); + + if (CollectionUtil.isNotEmpty(shopOrderReturns)) { + // 获取这些退款单对应的商品ID + List returnIds = shopOrderReturns.stream() + .map(ShopOrderReturn::getReturn_id) + .collect(Collectors.toList()); + + QueryWrapper returnItemQueryWrapper = new QueryWrapper<>(); + returnItemQueryWrapper.in("return_id", returnIds); + List returnItems = orderReturnItemService.find(returnItemQueryWrapper); + + if (CollectionUtil.isNotEmpty(returnItems)) { + refundedItemIds = returnItems.stream() + .map(ShopOrderReturnItem::getOrder_item_id) + .collect(Collectors.toSet()); + } + } + + return refundedItemIds; + } + + /** * 订单流转到供应商 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index 5721b9ce..124aee9c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -809,66 +809,99 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { /** * 接收顺丰原因订单取消回调 + *

+ * 该方法用于处理顺丰同城配送订单取消的回调通知。当顺丰因为某种原因取消订单时, + * 会调用此接口通知商城系统,商城系统需要更新订单状态为已取消,并执行相关业务逻辑。 + *

* - * @param jsonData - * @param sign - * @return + * @param jsonData 包含订单取消信息的JSON数据 + * @param sign 请求签名,用于验证请求的合法性 + * @return ThirdApiRes 处理结果响应对象 + *
    + *
  • 成功: {"error_code": 0, "reason": "success"}
  • + *
  • 失败: {"error_code": 错误码, "reason": "错误信息"}
  • + *
*/ @Override public ThirdApiRes receiveCancelOrderNotify(String jsonData, String sign) { + // 参数校验 if (StrUtil.isBlank(jsonData) || StrUtil.isBlank(sign)) { + logger.warn("[顺丰订单取消回调] 缺少必要参数: jsonData或sign为空"); return new ThirdApiRes().fail(1003, "缺少必要参数!"); } + // 签名校验 if (!checkOpenSign(sign, jsonData)) { + logger.warn("[顺丰订单取消回调] 请求签名sign校验失败"); return new ThirdApiRes().fail(2002, "请求签名sign校验失败!"); } - logger.info("接收顺丰原因订单取消回调返回的 JSON 数据:{}", jsonData); + logger.info("[顺丰订单取消回调] 接收回调数据: {}", jsonData); - // 更改顺丰同城订单状态 - ShopStoreSfOrder shopStoreSfOrder = toShopStoreSfOrder(jsonData); - - String shopOrderId = shopStoreSfOrder.getShop_order_id(); - String sfOrderId = shopStoreSfOrder.getSf_order_id(); - // 判断订单的状态,是否已经取消了?已取消,不再执行 - ShopStoreSfOrder shopStoreSfOrderExist = shopStoreSfOrderService.getBySfOrderId(sfOrderId); - if (shopStoreSfOrderExist != null && shopStoreSfOrderExist.getOrder_status() != null - && (shopStoreSfOrderExist.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELED) || - (shopStoreSfOrderExist.getOrder_status().equals(StateCode.SF_ORDER_STATUS_CANCELING)))) { - return new ThirdApiRes().success("success"); - } - - Boolean success = shopStoreSfOrderService.updateShopStoreSfOrderStatus(shopStoreSfOrder); - if (!success) { - return new ThirdApiRes().fail(-1, "状态处理失败!"); - } - - // 重要:更改商城订单状态为:已取消,注意事务问题 - success = shopOrderReturnService.sfExpressExpiredForceRefund(shopOrderId); - if (!success) { - return new ThirdApiRes().fail(-1, "取消订单业务处理失败!"); - } - - // 获取顺丰同城的物流轨迹 - Map params = new HashMap<>(); - params.put("order_id", sfOrderId); - ThirdApiRes feedRes = listOrderFeed(params); - if (feedRes != null && feedRes.getError_code().equals(0)) { - JSONObject result = JSONUtil.parseObj(feedRes.getResult()); - if (result != null && result.get("feed") != null) { - shopStoreSfOrder.setFeed(JSONUtil.toJsonStr(result.get("feed"))); + try { + // 解析并更新顺丰同城订单状态 + ShopStoreSfOrder shopStoreSfOrder = toShopStoreSfOrder(jsonData); + if (shopStoreSfOrder == null) { + logger.error("[顺丰订单取消回调] 解析订单数据失败: jsonData={}", jsonData); + return new ThirdApiRes().fail(-1, "订单数据解析失败!"); } + + String shopOrderId = shopStoreSfOrder.getShop_order_id(); + String sfOrderId = shopStoreSfOrder.getSf_order_id(); + + logger.info("[顺丰订单取消回调] 处理订单取消: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId); + + // 判断订单的状态,是否已经取消了?已取消,不再执行 + ShopStoreSfOrder shopStoreSfOrderExist = shopStoreSfOrderService.getBySfOrderId(sfOrderId); + if (shopStoreSfOrderExist != null && shopStoreSfOrderExist.getOrder_status() != null + && (ObjectUtil.equal(shopStoreSfOrderExist.getOrder_status(), StateCode.SF_ORDER_STATUS_CANCELED) || + ObjectUtil.equal(shopStoreSfOrderExist.getOrder_status(), StateCode.SF_ORDER_STATUS_CANCELING))) { + logger.info("[顺丰订单取消回调] 订单已处于取消状态,无需重复处理: sfOrderId={} status={}", + sfOrderId, shopStoreSfOrderExist.getOrder_status()); + return new ThirdApiRes().success("success"); + } + + // 更新顺丰订单状态 + Boolean success = shopStoreSfOrderService.updateShopStoreSfOrderStatus(shopStoreSfOrder); + if (!success) { + logger.error("[顺丰订单取消回调] 更新顺丰订单状态失败: sfOrderId={}", sfOrderId); + return new ThirdApiRes().fail(-1, "状态处理失败!"); + } + logger.debug("[顺丰订单取消回调] 顺丰订单状态更新成功: sfOrderId={}", sfOrderId); + + // 重要:更改商城订单状态为:已取消,注意事务问题 + success = shopOrderReturnService.sfExpressExpiredForceRefund(shopOrderId); + if (!success) { + logger.error("[顺丰订单取消回调] 取消商城订单业务处理失败: shopOrderId={}", shopOrderId); + return new ThirdApiRes().fail(-1, "取消订单业务处理失败!"); + } + logger.debug("[顺丰订单取消回调] 商城订单取消处理成功: shopOrderId={}", shopOrderId); + + // 获取顺丰同城的物流轨迹 + Map params = new HashMap<>(); + params.put("order_id", sfOrderId); + ThirdApiRes feedRes = listOrderFeed(params); + if (feedRes != null && ObjectUtil.equal(feedRes.getError_code(), 0)) { + JSONObject result = JSONUtil.parseObj(feedRes.getResult()); + if (result != null && result.get("feed") != null) { + shopStoreSfOrder.setFeed(JSONUtil.toJsonStr(result.get("feed"))); + logger.debug("[顺丰订单取消回调] 获取物流轨迹成功: sfOrderId={}", sfOrderId); + } + } + + // 个推推送消息 + JSONObject payload = new JSONObject(); + payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL); + payload.put("orderId", shopOrderId); + pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔取消订单", "您有一笔取消订单[" + shopOrderId + "],请及时处理。", payload); + logger.info("[顺丰订单取消回调] 推送消息完成: shopOrderId={}", shopOrderId); + + logger.info("[顺丰订单取消回调] 处理完成: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId); + return new ThirdApiRes().success("success"); + } catch (Exception e) { + logger.error("[顺丰订单取消回调] 处理过程中发生异常", e); + return new ThirdApiRes().fail(-1, "系统处理异常: " + e.getMessage()); } - - // 个推推送消息 - JSONObject payload = new JSONObject(); - payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL); - payload.put("orderId", shopOrderId); - pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔取消订单", "您有一笔取消订单[" + shopOrderId + "],请及时处理。", null); - - - return new ThirdApiRes().success("success"); } /** @@ -959,7 +992,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { // 顺丰同城状态:17-配送员妥投完单; // orderStatus = StateCode.ORDER_STATE_FINISH; pushRemark = "已完成配送"; - orderStatus = StateCode.ORDER_STATE_RECEIVED; + orderStatus = StateCode.ORDER_STATE_RECEIVED; //已签收 // 通知微信用户确认收货(同城配送不能调用微信的确认收货) // wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id()); diff --git a/pom.xml b/pom.xml index 2f8428cf..02cd8440 100644 --- a/pom.xml +++ b/pom.xml @@ -517,7 +517,7 @@ org.springframework.boot spring-boot-maven-plugin - + true @@ -529,13 +529,13 @@ - org.apache.maven.plugins maven-dependency-plugin + com.spotify docker-maven-plugin @@ -557,7 +557,6 @@ ${docker.host} - openjdk:8-jre ["java", "-jar", "-Xms256m", "-Xmx512m", "-XX:MetaspaceSize=256m", "-XX:MaxMetaspaceSize=256m", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=60.0", "-XX:+UseSerialGC", "-XX:MinHeapFreeRatio=40", "-XX:MaxHeapFreeRatio=60", "-XX:+PrintGCDetails", "-XX:+PrintGCDateStamps", "-Xloggc:./gc.log", "-XX:+UseGCLogFileRotation", "-XX:NumberOfGCLogFiles=5", "-XX:GCLogFileSize=10M", "-Dspring.profiles.active=${spring.profile}", "-Duser.timezone=Asia/Shanghai", "/${project.build.finalName}.jar"] @@ -568,16 +567,27 @@ - - rm -rf /var/cache/apk/* - - rm -rf /root/.m2 - - find / -name "*.log" -type f -delete 2>/dev/null || true - - find / -name "*test*" -type f -delete 2>/dev/null || true - - find / -name "*.md" -type f -delete 2>/dev/null || true + + rm -rf /var/cache/apk/* + rm -rf /root/.m2 + find / -name "*.log" -type f -delete 2>/dev/null || true + find / -name "*test*" -type f -delete 2>/dev/null || true + find / -name "*.md" -type f -delete 2>/dev/null || true + + + rm -rf /tmp/* /var/tmp/* + + rm -rf /usr/share/doc/* /usr/share/man/* /usr/share/info/* + + rm -rf /var/cache/yum/* /var/cache/dnf/* 2>/dev/null || true + + rm -rf /tmp/*.tar.gz /tmp/*.zip /app/*.tar.gz 2>/dev/null || true + + apk del --purge vim curl wget tar gzip 2>/dev/null || true + + rm -rf /root/.java /tmp/hsperfdata_* 2>/dev/null || true + + find / -type d -empty -delete 2>/dev/null || true @@ -591,6 +601,7 @@ +