From d6027e48eb4cb16a965af0ddf4b9ad5ddc7c64ac Mon Sep 17 00:00:00 2001 From: WrBug Date: Fri, 2 Jan 2026 04:13:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E8=AF=AF=E5=88=A0=E8=AE=A2=E5=8D=95=E5=92=8C?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 先检查 HTTP 状态码,非 200 的都跳过,不删除订单 - 只有当 HTTP 200 且响应体为 null 时,才表示订单不存在 - 保护已部分卖出的订单,如果已部分卖出则保留用于统计 - 避免因临时网络问题或 API 错误导致订单和 sell_match_detail 被误删 --- .../statistics/OrderStatusUpdateService.kt | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/OrderStatusUpdateService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/OrderStatusUpdateService.kt index 88d12ae..ad6fa12 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/OrderStatusUpdateService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/OrderStatusUpdateService.kt @@ -199,22 +199,29 @@ class OrderStatusUpdateService( // 查询订单详情 val orderResponse = clobApi.getOrder(order.buyOrderId) - if (!orderResponse.isSuccessful) { - // HTTP 错误,可能是订单不存在,删除 - logger.info("订单查询失败(HTTP错误),删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, code=${orderResponse.code()}") - try { - copyOrderTrackingRepository.deleteById(order.id!!) - logger.info("已删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}") - } catch (e: Exception) { - logger.error("删除本地订单失败: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, error=${e.message}", e) - } + // 先检查 HTTP 状态码,非 200 的都跳过 + if (orderResponse.code() != 200) { + // HTTP 非 200,记录日志并跳过,等待下次轮询 + // 不删除订单,因为可能是临时网络问题或 API 错误 + val errorBody = orderResponse.errorBody()?.string()?.take(200) ?: "无错误详情" + logger.debug("订单查询失败(HTTP非200),等待下次轮询: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, code=${orderResponse.code()}, errorBody=$errorBody") continue } + // HTTP 200,检查响应体 + // 响应体也可能返回字符串 "null",Gson 解析时会返回 null val orderDetail = orderResponse.body() if (orderDetail == null) { - // HTTP 200 但响应体为空,表示订单不存在,删除 - logger.info("订单不存在(响应体为空),删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, code=${orderResponse.code()}") + // HTTP 200 且响应体为 null(或字符串 "null"),表示订单不存在 + // 检查订单是否已部分卖出,如果已部分卖出则保留订单用于统计 + val hasMatchedDetails = sellMatchDetailRepository.findByTrackingId(order.id!!).isNotEmpty() + if (hasMatchedDetails || order.matchedQuantity > BigDecimal.ZERO) { + logger.debug("订单不存在但已部分卖出,保留订单用于统计: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, matchedQuantity=${order.matchedQuantity}") + continue + } + + // 订单不存在且未部分卖出,删除本地订单 + logger.info("订单不存在(HTTP 200 但响应体为空),删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}") try { copyOrderTrackingRepository.deleteById(order.id!!) logger.info("已删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}") @@ -577,16 +584,28 @@ class OrderStatusUpdateService( // 查询订单详情 val orderResponse = clobApi.getOrder(order.buyOrderId) - if (!orderResponse.isSuccessful) { + + // 先检查 HTTP 状态码,非 200 的都跳过 + if (orderResponse.code() != 200) { val errorBody = orderResponse.errorBody()?.string()?.take(200) ?: "无错误详情" - logger.debug("查询订单详情失败,等待下次轮询: orderId=${order.buyOrderId}, code=${orderResponse.code()}, errorBody=$errorBody") + logger.debug("查询订单详情失败(HTTP非200),等待下次轮询: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, code=${orderResponse.code()}, errorBody=$errorBody") continue } + // HTTP 200,检查响应体 + // 响应体也可能返回字符串 "null",Gson 解析时会返回 null val orderDetail = orderResponse.body() if (orderDetail == null) { - // HTTP 200 但响应体为空,表示订单不存在(没有交易成功),删除本地订单 - logger.info("订单不存在(响应体为空),删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, code=${orderResponse.code()}") + // HTTP 200 且响应体为 null(或字符串 "null"),表示订单不存在 + // 检查订单是否已部分卖出,如果已部分卖出则保留订单用于统计 + val hasMatchedDetails = sellMatchDetailRepository.findByTrackingId(order.id!!).isNotEmpty() + if (hasMatchedDetails || order.matchedQuantity > BigDecimal.ZERO) { + logger.debug("订单不存在但已部分卖出,保留订单用于统计: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}, matchedQuantity=${order.matchedQuantity}") + continue + } + + // 订单不存在且未部分卖出,删除本地订单 + logger.info("订单不存在(HTTP 200 但响应体为空),删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}") try { copyOrderTrackingRepository.deleteById(order.id!!) logger.info("已删除本地订单: orderId=${order.buyOrderId}, copyOrderTrackingId=${order.id}")