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 @@
+