diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderInfo.java b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderInfo.java index 0b5ab844..5fe5661b 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderInfo.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderInfo.java @@ -75,7 +75,7 @@ public class ShopOrderInfo implements Serializable { @ApiModelProperty(value = "下单时间:检索使用") private Long order_time; - @ApiModelProperty(value = "当前状态的处理时间") + @ApiModelProperty(value = "当前状态的处理时间,一般是确认收货时间") private Long order_deal_time; @ApiModelProperty(value = "买家删除(BOOL): 1-是; 0-否") @@ -204,6 +204,15 @@ public class ShopOrderInfo implements Serializable { @ApiModelProperty(value = "拣货完成时间戳") private Long order_picked_time; + @ApiModelProperty(value = "订单配送预约状态:1-立即配送;2-预约配送") + private Integer booking_state; + + @ApiModelProperty(value = "预约送达起始时间,格式如:10:15") + private String booking_begin_time; + + @ApiModelProperty(value = "预约送达截止时间,格式如:10:45") + private String booking_end_time; + @ApiModelProperty(value = "新建时间") private Date created_at; 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 dffb287d..ba7fe700 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 @@ -3050,9 +3050,9 @@ public class LakalaApiServiceImpl implements LakalaApiService { public Integer fixUnSuccessSeparateStatusJob() { log.info("[分账状态修复任务] 开始执行未成功分账记录的状态修复任务"); - // 获取2天前分账状态未成功的记录 - Date now = new Date(); - Date threeDaysAgo = DateUtils.addHours(now, -48); + // 获取3天前分账状态未成功的记录 + Date endDate = new Date(); + Date beginDate = DateUtils.addDays(endDate, -3); // 3天前 // 分页参数 int pageSize = 200; @@ -3062,100 +3062,104 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 记录处理开始时间 long startTime = System.currentTimeMillis(); + String redisPrefKey = "lkl:separate:status:retry:"; - List lklOrderSeparates; - do { - // 分页获取未成功分账的记录 - lklOrderSeparates = lklOrderSeparateService.getUnSuccessSeparateList(threeDaysAgo, now, currentPage, pageSize); + try { + List lklOrderSeparates; + do { + // 分页获取未成功分账的记录 + lklOrderSeparates = lklOrderSeparateService.getUnSuccessSeparateList(beginDate, endDate, currentPage, pageSize); - if (CollectionUtil.isEmpty(lklOrderSeparates)) { - break; - } - - log.info("[分账状态修复任务] 获取到第{}页数据,共{}条记录", currentPage, lklOrderSeparates.size()); - - String redisPrefKey = "lkl:separate:status:retry:"; - - // 按处理次数排序,从未处理过的记录优先处理,处理次数越多优先级越低 - lklOrderSeparates.sort((o1, o2) -> { - String redisKey1 = redisPrefKey + o1.getSeparate_no(); - String redisKey2 = redisPrefKey + o2.getSeparate_no(); - - int retryCount1 = Convert.toInt(redisService.get(redisKey1), 0); - int retryCount2 = Convert.toInt(redisService.get(redisKey2), 0); - - return Integer.compare(retryCount1, retryCount2); - }); - - // 处理当前页中的记录 - for (LklOrderSeparate record : lklOrderSeparates) { - // 检查该记录的处理次数是否已达到上限(5次) - String redisKey = redisPrefKey + record.getSeparate_no(); - int retryCount = Convert.toInt(redisService.get(redisKey), 0); - - if (retryCount >= 5) { - log.warn("[分账状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, separateNo={}", - record.getMerchant_no(), record.getSeparate_no()); - continue; + if (CollectionUtil.isEmpty(lklOrderSeparates)) { + break; } - totalProcessed++; - // 每处理10条记录才输出一次详细日志,减少日志量 - if (totalProcessed % 10 == 1) { - log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次", - totalProcessed, record.getMerchant_no(), record.getSeparate_no(), retryCount); - } + log.info("[分账状态修复任务] 获取到第{}页数据,共{}条记录", currentPage, lklOrderSeparates.size()); - try { - // 增加处理次数计数并设置3天过期时间 - redisService.incr(redisKey, 1); - redisService.expire(redisKey, 3 * 24 * 60 * 60); + // 按处理次数排序,从未处理过的记录优先处理,处理次数越多优先级越低 + lklOrderSeparates.sort((o1, o2) -> { + String redisKey1 = redisPrefKey + o1.getSeparate_no(); + String redisKey2 = redisPrefKey + o2.getSeparate_no(); - // 调用分账通知回调接口进行状态补偿 - JSONObject notifyResp = sacsSeparateNotify(null, record.getMerchant_no(), record.getSeparate_no()); + int retryCount1 = Convert.toInt(redisService.get(redisKey1), 0); + int retryCount2 = Convert.toInt(redisService.get(redisKey2), 0); - // 检查处理结果 - if (notifyResp != null && "SUCCESS".equals(notifyResp.getStr("code"))) { - totalSuccessCount++; - log.debug("[分账状态修复任务] 记录处理成功: merchantNo={}, separateNo={}", + return Integer.compare(retryCount1, retryCount2); + }); + + // 处理当前页中的记录 + for (LklOrderSeparate record : lklOrderSeparates) { + // 检查该记录的处理次数是否已达到上限(5次) + String redisKey = redisPrefKey + record.getSeparate_no(); + int retryCount = Convert.toInt(redisService.get(redisKey), 0); + + if (retryCount >= 5) { + log.warn("[分账状态修复任务] 记录已达到最大重试次数,跳过处理: merchantNo={}, separateNo={}", record.getMerchant_no(), record.getSeparate_no()); - } else { - String errorMsg = notifyResp != null ? notifyResp.getStr("message") : "未知错误"; - log.warn("[分账状态修复任务] 记录处理失败: merchantNo={}, separateNo={}, errorMsg={}", - record.getMerchant_no(), record.getSeparate_no(), errorMsg); + continue; + } + + totalProcessed++; + // 每处理10条记录才输出一次详细日志,减少日志量 + if (totalProcessed % 10 == 1) { + log.info("[分账状态修复任务] 正在处理第 {} 条记录: merchantNo={}, separateNo={}, 已重试{}次", + totalProcessed, record.getMerchant_no(), record.getSeparate_no(), retryCount); + } + + try { + // 增加处理次数计数并设置3天过期时间 + redisService.incr(redisKey, 1); + redisService.expire(redisKey, 3 * 24 * 60 * 60); + + // 调用拉卡拉分账通知回调接口进行状态补偿 + JSONObject notifyResp = sacsSeparateNotify(null, record.getMerchant_no(), record.getSeparate_no()); + + // 检查处理结果 + if (notifyResp != null && "SUCCESS".equals(notifyResp.getStr("code"))) { + totalSuccessCount++; + log.debug("[分账状态修复任务] 记录处理成功: merchantNo={}, separateNo={}", + record.getMerchant_no(), record.getSeparate_no()); + } else { + String errorMsg = notifyResp != null ? notifyResp.getStr("message") : "未知错误"; + log.warn("[分账状态修复任务] 记录处理失败: merchantNo={}, separateNo={}, errorMsg={}", + record.getMerchant_no(), record.getSeparate_no(), errorMsg); + } + } catch (Exception e) { + log.error("[分账状态修复任务] 处理记录时发生异常: merchantNo={}, separateNo={}", + record.getMerchant_no(), record.getSeparate_no(), e); } - } catch (Exception e) { - log.error("[分账状态修复任务] 处理记录时发生异常: merchantNo={}, separateNo={}", - record.getMerchant_no(), record.getSeparate_no(), e); } - } - log.info("[分账状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条", - currentPage, totalProcessed, totalSuccessCount); + log.info("[分账状态修复任务] 第{}页处理完成,已处理 {} 条记录,总成功 {} 条", + currentPage, totalProcessed, totalSuccessCount); - // 如果当前页数据少于页面大小,说明已经是最后一页 - if (lklOrderSeparates.size() < pageSize) { - break; - } + // 如果当前页数据少于页面大小,说明已经是最后一页 + if (lklOrderSeparates.size() < pageSize) { + break; + } - currentPage++; + currentPage++; - // 添加短暂延迟,避免对系统造成过大压力 - try { + // 添加短暂延迟,避免对系统造成过大压力 Thread.sleep(100); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - break; - } - } while (!CollectionUtil.isEmpty(lklOrderSeparates)); + } while (!CollectionUtil.isEmpty(lklOrderSeparates)); + + } catch (InterruptedException e) { + log.warn("[分账状态修复任务] 任务被中断"); + Thread.currentThread().interrupt(); + } catch (Exception e) { + log.error("[分账状态修复任务] 任务执行过程中发生异常", e); + } long endTime = System.currentTimeMillis(); log.info("[分账状态修复任务] 任务执行完成,总共处理 {} 条记录,成功处理 {} 条记录,耗时 {} ms", totalProcessed, totalSuccessCount, (endTime - startTime)); + return totalSuccessCount; } + /** * 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制) * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java index a506e727..6cbbe8dc 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java @@ -9,6 +9,7 @@ import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.constant.MqConstant; import com.suisung.mall.common.constant.RedisConstant; import com.suisung.mall.common.modules.order.ShopOrderInfo; +import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.DateTimeUtils; import com.suisung.mall.core.web.service.RedisService; import com.suisung.mall.shop.message.service.PushMessageService; @@ -138,10 +139,10 @@ public class OrderPayedListener { } } - logger.info("[订单支付监听] 支付异步通知回调处理结果: {}, 订单ID: {}", flag, orderId); + logger.info("[订单支付监听] 订单ID: {},支付异步通知回调处理是否成功: {} ", flag, orderId); + // 生成取单号和打印小票 if (flag) { - // TODO 以下仅处理下单打印的情况,还需要处理退单打印分支。 // 原始状态 2010-待付款;2011--待订单审核;2013-待财务审核 变成 2020-待配货;2016-已经付款 的时候 // 生成取单号,打票机打印订单,向顺丰同城下单 @@ -152,12 +153,14 @@ public class OrderPayedListener { Long orderPickupNum = shopOrderInfoService.isPaidOrderGenPickNumAndPrint(orderInfoOld.getStore_id(), orderId); // 如果配送方式是 顺丰同城下单 - if (orderInfoOld.getDelivery_type_id() != null && orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY) - && orderPickupNum > 0) { - // 发送顺丰同城快递 + if (CheckUtil.isNotEmpty(orderInfoOld.getDelivery_type_id()) + && orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY) + && CheckUtil.isNotEmpty(orderPickupNum)) { + + // 顺丰同城下单 Pair pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum); if (pairCreateSfOrder == null) { - logger.error("[订单支付监听] 顺丰同城下单失败!pairCreateSfOrder 返回空值. 订单ID: {}", orderId); + logger.error("[订单支付监听] 顺丰同城下单失败,无返回值 订单ID: {}", orderId); continue; } diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderInfoMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderInfoMapper.xml index 11d0ac88..2ebafc3f 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderInfoMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderInfoMapper.xml @@ -11,7 +11,8 @@ order_is_received, chain_id, delivery_type_id, order_is_offline, cart_type_id, order_express_print, activity_id, activity_type_id, salesperson_id, order_is_sync, store_is_selfsupport, store_type, order_erp_id, distributor_user_id, order_is_cb, order_is_cb_sync, src_order_id, order_is_transfer, order_is_transfer_note, - order_fx_is_settlemented, order_fx_settlement_time, order_pickup_num,order_picked_notice_count,order_picked_time + order_fx_is_settlemented, order_fx_settlement_time, order_pickup_num,order_picked_notice_count,order_picked_time, + booking_state, booking_begin_time, booking_end_time,created_at, updated_at