* 阶段1包含:
* 1. 检查账号状态
* 2. 发送ACK确认
@@ -2538,7 +2556,7 @@ public class XianyuClient extends TextWebSocketHandler {
String orderId = extractOrderId(message);
if (orderId != null) {
String msgTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
- .format(new java.util.Date());
+ .format(new java.util.Date());
log.info("[{}] 【{}】✅ 检测到订单ID: {},开始获取订单详情", msgTime, cookieId, orderId);
// 提取用户ID和商品ID用于订单详情获取
@@ -2563,7 +2581,7 @@ public class XianyuClient extends TextWebSocketHandler {
try {
log.info("【{}】🔍 完整消息结构: {}", cookieId, message.toJSONString());
String msgTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
- .format(new java.util.Date());
+ .format(new java.util.Date());
// 安全地检查订单状态(红色提醒)
String redReminder = null;
@@ -2607,7 +2625,7 @@ public class XianyuClient extends TextWebSocketHandler {
String chatId;
long createTime;
String itemId;
-
+
try {
// 安全地提取聊天消息信息
if (!message.containsKey("1") || !(message.get("1") instanceof JSONObject)) {
@@ -2623,7 +2641,7 @@ public class XianyuClient extends TextWebSocketHandler {
// 提取消息时间
createTime = message1.getLongValue("5");
-
+
// 提取消息详情
JSONObject message10 = message1.getJSONObject("10");
sendUserName = message10.getString("senderNick");
@@ -2659,23 +2677,23 @@ public class XianyuClient extends TextWebSocketHandler {
// 格式化消息时间
String msgTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
- .format(new java.util.Date(createTime));
+ .format(new java.util.Date(createTime));
// ========== 步骤9: 判断消息方向 ==========
// 对应Python: Line 7561-7568
if (sendUserId.equals(myId)) {
log.info("[{}] 【手动发出】 商品({}): {}", msgTime, itemId, sendMessage);
-
+
// 暂停该chat_id的自动回复10分钟
pauseManager.pauseChat(chatId, cookieId);
-
+
return;
}
-
+
// ========== 步骤10: 消息通知 ==========
// 对应Python: Line 7569-7582
- log.info("[{}] 【收到】用户: {} (ID: {}), 商品({}): {}",
- msgTime, sendUserName, sendUserId, itemId, sendMessage);
+ log.info("[{}] 【收到】用户: {} (ID: {}), 商品({}): {}",
+ msgTime, sendUserName, sendUserId, itemId, sendMessage);
// 🔔 立即发送消息通知(独立于自动回复功能)
// 检查是否为群组消息,如果是群组消息则跳过通知
@@ -2686,7 +2704,7 @@ public class XianyuClient extends TextWebSocketHandler {
if (sessionType == null) {
sessionType = "1"; // 默认为个人消息类型
}
-
+
if ("30".equals(sessionType)) {
log.info("📱 检测到群组消息(sessionType=30),跳过消息通知");
} else {
@@ -2697,7 +2715,7 @@ public class XianyuClient extends TextWebSocketHandler {
final String finalSendMessage = sendMessage;
final String finalItemId = itemId;
final String finalChatId = chatId;
-
+
CompletableFuture.runAsync(() -> {
try {
// 发送消息通知(简化版 - 实际应调用NotificationService)
@@ -2717,7 +2735,7 @@ public class XianyuClient extends TextWebSocketHandler {
try {
//处理系统消息的订单状态更新
orderStatusHandler.handleSystemMessage(message, sendMessage, cookieId, msgTime);
-
+
// 处理红色提醒消息
if (message.containsKey("3") && message.get("3") instanceof JSONObject) {
JSONObject message3 = message.getJSONObject("3");
@@ -2731,8 +2749,8 @@ public class XianyuClient extends TextWebSocketHandler {
log.error("【{}】订单状态处理失败: {}", cookieId, e.getMessage());
}
}
-
-
+
+
// ========== 步骤12: 系统消息过滤 ==========
// 对应Python: Line 7626-7662
// 检查并过滤15+种系统消息
@@ -2744,16 +2762,16 @@ public class XianyuClient extends TextWebSocketHandler {
// ========== 步骤13: 自动发货触发检查 ==========
// 对应Python: Line 7664-7669
if (isAutoDeliveryTrigger(sendMessage)) {
- log.info("[{}] 【{}】检测到自动发货触发消息,即使在暂停期间也继续处理: {}",
- msgTime, cookieId, sendMessage);
-
+ log.info("[{}] 【{}】检测到自动发货触发消息,即使在暂停期间也继续处理: {}",
+ msgTime, cookieId, sendMessage);
+
// 异步处理自动发货
final String finalSendUserName = sendUserName;
final String finalSendUserId = sendUserId;
final String finalItemId = itemId;
final String finalChatId = chatId;
final String finalMsgTime = msgTime;
-
+
CompletableFuture.runAsync(() -> {
try {
// 调用统一的自动发货处理方法(已在本类中实现)
@@ -2763,7 +2781,7 @@ public class XianyuClient extends TextWebSocketHandler {
log.error("【{}】自动发货处理失败", cookieId, e);
}
}, scheduledExecutor);
-
+
return;
}
@@ -2771,27 +2789,27 @@ public class XianyuClient extends TextWebSocketHandler {
// 对应Python: Line 7670-7749
if ("[卡片消息]".equals(sendMessage)) {
String cardTitle = extractCardTitle(message);
-
+
if ("我已小刀,待刀成".equals(cardTitle)) {
- log.info("[{}] 【{}】【系统】检测到\"我已小刀,待刀成\",即使在暂停期间也继续处理",
- msgTime, cookieId);
-
+ log.info("[{}] 【{}】【系统】检测到\"我已小刀,待刀成\",即使在暂停期间也继续处理",
+ msgTime, cookieId);
+
// 检查商品是否属于当前cookies
if (itemId != null && !itemId.startsWith("auto_")) {
// 商品归属验证(简化版 - 实际应查询数据库)
log.warn("[{}] 【{}】✅ 商品 {} 归属验证通过", msgTime, cookieId, itemId);
}
-
+
// 提取订单ID(使用已在2538行定义的orderId变量)
orderId = extractOrderId(message);
if (orderId == null) {
log.warn("[{}] 【{}】❌ 未能提取到订单ID,无法执行免拼发货", msgTime, cookieId);
return;
}
-
+
// 标记为小刀订单(简化版 - 实际应更新数据库)
log.info("[{}] 【{}】✅ 订单 {} 已标记为小刀订单", msgTime, cookieId, orderId);
-
+
// 异步执行免拼发货
final String finalOrderId = orderId;
final String finalItemId = itemId;
@@ -2799,27 +2817,27 @@ public class XianyuClient extends TextWebSocketHandler {
final String finalSendUserName = sendUserName;
final String finalChatId = chatId;
final String finalMsgTime = msgTime;
-
+
CompletableFuture.runAsync(() -> {
try {
// 延迟2秒
Thread.sleep(2000);
-
+
// 调用自动免拼发货方法(简化版 - 实际应调用API)
log.info("[{}] 【{}】延迟2秒后执行免拼发货(autoFreeShipping已调用)", finalMsgTime, cookieId);
-
+
// 然后执行自动发货(handleAutoDelivery方法已存在)
log.info("[{}] 【{}】免拼发货后继续自动发货流程", finalMsgTime, cookieId);
-
+
} catch (Exception e) {
log.error("【{}】处理免拼小刀异常", cookieId, e);
}
}, scheduledExecutor);
-
+
return;
} else {
- log.info("[{}] 【{}】收到卡片消息,标题: {}", msgTime, cookieId,
- cardTitle != null ? cardTitle : "未知");
+ log.info("[{}] 【{}】收到卡片消息,标题: {}", msgTime, cookieId,
+ cardTitle != null ? cardTitle : "未知");
// 不是目标卡片消息,继续正常处理流程
}
}
@@ -2834,7 +2852,7 @@ public class XianyuClient extends TextWebSocketHandler {
final String finalItemId = itemId;
final String finalChatId = chatId;
final String finalMsgTime = msgTime;
-
+
CompletableFuture.runAsync(() -> {
try {
// 防抖回复逻辑(简化版 - 实际需实现消息去重和防抖计时器)
@@ -2843,15 +2861,15 @@ public class XianyuClient extends TextWebSocketHandler {
// 2. 管理防抖任务Map
// 3. 取消旧任务并调度新任务
// 4. 延迟后调用processChatMessageReply
-
- log.info("【{}】防抖回复调度已启动: chatId={}, 用户={}, 消息={}",
- cookieId, finalChatId, finalSendUserName, finalSendMessage);
-
+
+ log.info("【{}】防抖回复调度已启动: chatId={}, 用户={}, 消息={}",
+ cookieId, finalChatId, finalSendUserName, finalSendMessage);
+
} catch (Exception e) {
log.error("【{}】防抖回复调度失败", cookieId, e);
}
}, scheduledExecutor);
-
+
log.debug("【{}】消息处理完成(阶段3 - 全部15个步骤)", cookieId);
} catch (Exception e) {
@@ -2862,7 +2880,7 @@ public class XianyuClient extends TextWebSocketHandler {
/**
* 解密消息内容
* 对应Python的消息解密逻辑 (Line 7336-7391)
- *
+ *
* @param messageData 原始消息数据
* @return 解密后的消息对象,失败返回null
*/
@@ -2870,9 +2888,9 @@ public class XianyuClient extends TextWebSocketHandler {
try {
// 获取同步数据
JSONObject syncData = messageData.getJSONObject("body")
- .getJSONObject("syncPushPackage")
- .getJSONArray("data")
- .getJSONObject(0);
+ .getJSONObject("syncPushPackage")
+ .getJSONArray("data")
+ .getJSONObject(0);
// 检查是否有必要的字段
if (!syncData.containsKey("data")) {
@@ -2881,29 +2899,29 @@ public class XianyuClient extends TextWebSocketHandler {
}
String data = syncData.getString("data");
-
+
// 尝试Base64解码 + JSON解析(对应Python的第一次尝试)
try {
byte[] decodedBytes = java.util.Base64.getDecoder().decode(data);
String decodedStr = new String(decodedBytes, "UTF-8");
JSONObject parsedData = JSON.parseObject(decodedStr);
-
+
// 检查是否为系统消息(对应Python Line 7354-7366)
if (parsedData.containsKey("chatType")) {
if (parsedData.containsKey("operation")) {
JSONObject operation = parsedData.getJSONObject("operation");
if (operation.containsKey("content")) {
JSONObject content = operation.getJSONObject("content");
-
+
// 处理系统引导消息
if (content.containsKey("sessionArouse")) {
String msgTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
- .format(new java.util.Date());
+ .format(new java.util.Date());
log.info("[{}] 【{}】【系统】小闲鱼智能提示(已跳过)", msgTime, cookieId);
return null;
} else if (content.containsKey("contentType")) {
String msgTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
- .format(new java.util.Date());
+ .format(new java.util.Date());
log.warn("[{}] 【{}】【系统】其他类型消息(已跳过)", msgTime, cookieId);
return null;
}
@@ -2911,10 +2929,10 @@ public class XianyuClient extends TextWebSocketHandler {
}
return null;
}
-
+
// 如果不是系统消息,返回解析的数据
return parsedData;
-
+
} catch (Exception e) {
// Base64解析失败,尝试解密(对应Python Line 7372-7373)
try {
@@ -2925,7 +2943,7 @@ public class XianyuClient extends TextWebSocketHandler {
return null;
}
}
-
+
} catch (Exception e) {
log.error("【{}】解密消息过程异常: {}", cookieId, e.getMessage());
return null;
@@ -2948,8 +2966,8 @@ public class XianyuClient extends TextWebSocketHandler {
JSONObject message1Obj = (JSONObject) message1;
if (message1Obj.containsKey("10") && message1Obj.get("10") instanceof JSONObject) {
JSONObject message10 = message1Obj.getJSONObject("10");
- return message10.getString("senderUserId") != null ?
- message10.getString("senderUserId") : "unknown_user";
+ return message10.getString("senderUserId") != null ?
+ message10.getString("senderUserId") : "unknown_user";
}
}
} catch (Exception e) {
@@ -2959,7 +2977,7 @@ public class XianyuClient extends TextWebSocketHandler {
}
/**
- * 提取商品ID
+ * 提取商品ID
* 对应Python: Line 7436-7445
*/
private String extractItemId(JSONObject message) {
@@ -2974,18 +2992,18 @@ public class XianyuClient extends TextWebSocketHandler {
}
}
}
-
+
// 如果没有提取到,调用辅助方法 extractItemIdFromMessage
// 对应Python: self.extract_item_id_from_message(message) (Line 3010-3084)
String extractedItemId = extractItemIdFromMessage(message);
if (extractedItemId != null) {
return extractedItemId;
}
-
+
} catch (Exception e) {
log.debug("【{}】提取商品ID失败: {}", cookieId, e.getMessage());
}
-
+
// 使用默认值
String userId = extractUserId(message);
return "auto_" + userId + "_" + System.currentTimeMillis();
@@ -2994,7 +3012,7 @@ public class XianyuClient extends TextWebSocketHandler {
/**
* 从消息中提取商品ID的辅助方法
* 对应Python: extract_item_id_from_message (Line 3010-3084)
- *
+ *
* @param message 消息对象
* @return 商品ID,提取失败返回null
*/
@@ -3015,7 +3033,7 @@ public class XianyuClient extends TextWebSocketHandler {
// 方法2: 从message["3"]中提取
if (message.containsKey("3") && message.get("3") instanceof JSONObject) {
JSONObject message3 = message.getJSONObject("3");
-
+
// 从extension中提取
if (message3.containsKey("extension") && message3.get("extension") instanceof JSONObject) {
JSONObject extension = message3.getJSONObject("extension");
@@ -3028,7 +3046,7 @@ public class XianyuClient extends TextWebSocketHandler {
return itemId;
}
}
-
+
// 从bizData中提取
if (message3.containsKey("bizData") && message3.get("bizData") instanceof JSONObject) {
JSONObject bizData = message3.getJSONObject("bizData");
@@ -3041,7 +3059,7 @@ public class XianyuClient extends TextWebSocketHandler {
return itemId;
}
}
-
+
// 从其他可能的字段中提取
for (Map.Entry