From 02346ebff058f1d6170d34f7a5366a0b6aa1fe93 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 8 Apr 2025 15:16:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E7=A6=BB=E7=A4=BC=E9=87=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/van/business/util/JDUtil.java | 874 ++++++------------ 1 file changed, 299 insertions(+), 575 deletions(-) diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index 2918118..34f65f1 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -182,11 +182,151 @@ public class JDUtil { return "地址格式不匹配"; } - public void sendOrderToWxByOrderDefault(String order, String fromWxid) { - logger.info("执行 sendOrderToWxByOrderDefault 方法,order: {}, fromWxid: {}", order, fromWxid); - handleUserInteraction(fromWxid, order); - // 具体逻辑 + public void sendOrderToWxByOrderDefault(String order, String fromWxid) { + logger.info("执行 sendOrderToWxByOrderDefault 方法,order: {}, fromWxid: {}", order, fromWxid); + + if ("礼".equals(order)) { + handleGiftCommand(fromWxid, cacheMap.get("giftMessage" + fromWxid)); + } else { + handleUserInteraction(fromWxid, order); + } + } + + +/** + * 处理“礼”指令,直接进入礼金创建流程 + */ +private void handleGiftCommand(String fromWxid, String message) { + try { + // 1. 提取 u.jd.com 链接 + List urls = extractUJDUrls(message); + if (urls.isEmpty()) { + wxUtil.sendTextMessage(fromWxid, "未找到有效的商品链接,请检查输入格式。", 1, fromWxid, false); + return; + } + + // 2. 查询商品信息,筛选有效商品 + List validProducts = new ArrayList<>(); + for (String url : urls) { + try { + GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url); + if (productInfo != null && productInfo.getCode() == 200 && productInfo.getTotalCount() > 0) { + validProducts.add(productInfo); + } + } catch (Exception e) { + logger.error("查询商品信息失败:{}", url, e); + } + } + + if (validProducts.isEmpty()) { + wxUtil.sendTextMessage(fromWxid, "未找到有效的商品信息,请检查链接是否正确。", 1, fromWxid, false); + return; + } + + // 3. 缓存商品信息 + String key = INTERACTION_STATE_PREFIX + fromWxid; + UserInteractionState state = loadOrCreateState(key); + + state.setCurrentState(UserInteractionState.ProcessState.GIFT_MONEY_FLOW); + state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_AMOUNT); + state.getCollectedFields().clear(); + state.getCollectedFields().put("productIndex", "0"); // 当前处理的商品索引 + state.getCollectedFields().put("totalProducts", String.valueOf(validProducts.size())); // 总商品数 + cacheMap.put("validProducts" + fromWxid, JSON.toJSONString(validProducts)); + + saveState(key, state); + + // 4. 提示用户输入金额 + wxUtil.sendTextMessage(fromWxid, "请输入开通金额(1-50元,支持小数点后两位):", 1, fromWxid, false); + + } catch (Exception e) { + logger.error("处理礼金指令异常 - 用户: {}", fromWxid, e); + wxUtil.sendTextMessage(fromWxid, "处理请求时发生异常,请重试", 1, fromWxid, false); } +} + +/** + * 礼金创建流程 - 循环处理商品 + */ +private void processGiftMoneyFlow(String wxid, String message, UserInteractionState state) { + try { + // 获取缓存的商品信息 + String cachedData = cacheMap.get("validProducts" + wxid); + if (cachedData == null) { + wxUtil.sendTextMessage(wxid, "数据丢失,请重新开始流程", 1, wxid, false); + resetState(wxid, state); + return; + } + + List validProducts = JSON.parseArray(cachedData, GoodsQueryResult.class); + int currentIndex = Integer.parseInt(state.getCollectedFields().get("productIndex")); + int totalProducts = Integer.parseInt(state.getCollectedFields().get("totalProducts")); + + // 根据当前步骤处理 + switch (state.getCurrentStep()) { + case STEP_AMOUNT: + if (!isValidAmount(message)) { + wxUtil.sendTextMessage(wxid, "金额格式错误,请输入1-50元", 1, wxid, false); + return; + } + state.getCollectedFields().put("amount", message); + state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_QUANTITY); + wxUtil.sendTextMessage(wxid, "请输入数量(1-100):", 1, wxid, false); + break; + + case STEP_QUANTITY: + if (!isValidQuantity(message)) { + wxUtil.sendTextMessage(wxid, "数量格式错误,请输入1-100的整数", 1, wxid, false); + return; + } + + // 记录数量 + state.getCollectedFields().put("quantity", message); + + // 开始循环创建礼金 + double amount = Double.parseDouble(state.getCollectedFields().get("amount")); + int quantity = Integer.parseInt(message); + + StringBuilder result = new StringBuilder(); + for (int i = currentIndex; i < totalProducts; i++) { + GoodsQueryResult product = validProducts.get(i); + JSONObject productInfo = JSONObject.parseObject(JSON.toJSONString(product.getData()[0])); + + String skuId = productInfo.getString("materialUrl"); + String owner = productInfo.getString("owner"); + String skuName = productInfo.getString("skuName"); + + // 调用礼金创建接口 + String giftKey = createGiftCoupon(skuId, amount, quantity, owner, skuName); + if (giftKey != null) { + result.append("商品:").append(skuName).append("\n") + .append("礼金创建成功,批次ID:").append(giftKey).append("\n\n"); + } else { + result.append("商品:").append(skuName).append("\n") + .append("礼金创建失败,请稍后重试。\n\n"); + } + + // 更新当前索引 + state.getCollectedFields().put("productIndex", String.valueOf(i + 1)); + saveState(INTERACTION_STATE_PREFIX + wxid, state); + } + + // 返回结果 + wxUtil.sendTextMessage(wxid, "礼金创建完成:\n" + result.toString(), 1, wxid, false); + resetState(wxid, state); + break; + + default: + wxUtil.sendTextMessage(wxid, "流程异常,请重新开始", 1, wxid, false); + resetState(wxid, state); + } + + } catch (Exception e) { + logger.error("礼金创建流程异常 - 用户: {}", wxid, e); + wxUtil.sendTextMessage(wxid, "处理异常,请重试", 1, wxid, false); + resetState(wxid, state); + } +} public void cjwlm(String message) { logger.info("执行 cjwlm 方法,order: {}", message); @@ -724,39 +864,39 @@ public class JDUtil { }); } - private void handleUserInteraction(String fromWxid, String message) { - String key = INTERACTION_STATE_PREFIX + fromWxid; - UserInteractionState state = loadOrCreateState(key); + private void handleUserInteraction(String fromWxid, String message) { + String key = INTERACTION_STATE_PREFIX + fromWxid; + UserInteractionState state = loadOrCreateState(key); - try { - switch (state.getCurrentState()) { - case INIT: - handleInitState(fromWxid, message, state); - break; + try { + switch (state.getCurrentState()) { + case INIT: + handleInitState(fromWxid, message, state); + break; - case PRODUCT_PROMOTION: - handlePromotionState(fromWxid, message, state); - break; + case PRODUCT_PROMOTION: + handlePromotionState(fromWxid, message, state); + break; - case GIFT_MONEY_FLOW: - handleGiftMoneyFlow(fromWxid, message, state); - break; + case GIFT_MONEY_FLOW: + processGiftMoneyFlow(fromWxid, message, state); + break; - default: - resetState(fromWxid, state); - wxUtil.sendTextMessage(fromWxid, "流程异常,请重新开始", 1, fromWxid, false); - } - } catch (Exception e) { - logger.error("流程处理异常 - 用户: {}, 状态: {}", fromWxid, state, e); - resetState(fromWxid, state); - wxUtil.sendTextMessage(fromWxid, "处理异常,请重新开始", 1, fromWxid, false); - } finally { - saveState(key, state); - } + default: + resetState(fromWxid, state); + wxUtil.sendTextMessage(fromWxid, "流程异常,请重新开始", 1, fromWxid, false); + } + } catch (Exception e) { + logger.error("流程处理异常 - 用户: {}, 状态: {}", fromWxid, state, e); + resetState(fromWxid, state); + wxUtil.sendTextMessage(fromWxid, "处理异常,请重新开始", 1, fromWxid, false); + } finally { + saveState(key, state); + } - userInteractionStates.put(key, state); - logger.debug("Updated interaction state for user {}: {}", fromWxid, JSON.toJSONString(state)); - } + userInteractionStates.put(key, state); + logger.debug("Updated interaction state for user {}: {}", fromWxid, JSON.toJSONString(state)); + } private UserInteractionState loadOrCreateState(String key) { UserInteractionState state = loadState(key); @@ -943,29 +1083,30 @@ public class JDUtil { * @param message 用户回复(1或2) * @param state 当前交互状态 */ - private void handleGiftMoneyConfirmation(String wxid, String message, UserInteractionState state) { - try { - if ("1".equals(message)) { - // 用户选择开通礼金 - state.setCurrentState(UserInteractionState.ProcessState.GIFT_MONEY_FLOW); - state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_AMOUNT); - state.getCollectedFields().clear(); +private void handleGiftMoneyConfirmation(String wxid, String message, UserInteractionState state) { + try { + if ("1".equals(message)) { + // 用户选择开通礼金 + state.setCurrentState(UserInteractionState.ProcessState.GIFT_MONEY_FLOW); + state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_AMOUNT); + state.getCollectedFields().clear(); - wxUtil.sendTextMessage(wxid, - "请输入开通金额(1-50元,支持小数点后两位):\n" + - "示例:20.50", - 1, wxid, false); + wxUtil.sendTextMessage(wxid, + "请输入开通金额(1-50元,支持小数点后两位):\n" + + "示例:20.50", + 1, wxid, false); - } else if ("2".equals(message)) { - // 用户选择不开通礼金 - String cachedData = cacheMap.get("productData" + wxid); - if (cachedData != null) { - JSONObject productInfo = JSON.parseObject(cachedData); - String skuUrl = productInfo.getString("materialUrl"); - String transferUrl = transfer(skuUrl, null); - String finalWenAn = cacheMap.get("finalWenAn" + wxid); + } else if ("2".equals(message)) { + // 用户选择不开通礼金 + String cachedData = cacheMap.get("productData" + wxid); + if (cachedData != null) { + JSONObject productInfo = JSON.parseObject(cachedData); + String skuUrl = productInfo.getString("materialUrl"); + String transferUrl = transfer(skuUrl, null); + String finalWenAn = cacheMap.get("finalWenAn" + wxid); - finalWenAn = (finalWenAn.replace(productInfo.getString("url"), transferUrl)); + if (finalWenAn != null) { + finalWenAn = finalWenAn.replace(productInfo.getString("url"), transferUrl); wxUtil.sendTextMessage(wxid, "不开礼金,只转链的方案:\n", 1, wxid, false); @@ -975,180 +1116,37 @@ public class JDUtil { } else { wxUtil.sendTextMessage(wxid, "未找到商品信息,请重新开始流程", 1, wxid, false); } - state.reset(); - cacheMap.remove("productData" + wxid); - cacheMap.remove("finalWenAn" + wxid); - - } else { - // 无效输入 - wxUtil.sendTextMessage(wxid, - "请输入有效选项:\n" + - "回复 1 - 开通礼金\n" + - "回复 2 - 直接转链", - 1, wxid, false); + wxUtil.sendTextMessage(wxid, "未找到商品信息,请重新开始流程", 1, wxid, false); } - } catch (Exception e) { - logger.error("处理礼金确认异常 - 用户: {}", wxid, e); - wxUtil.sendTextMessage(wxid, "处理请求时发生异常,请重试", 1, wxid, false); + + // 清理状态和缓存 state.reset(); + cacheMap.remove("productData" + wxid); + cacheMap.remove("finalWenAn" + wxid); + + } else { + // 无效输入 + wxUtil.sendTextMessage(wxid, + "请输入有效选项:\n" + + "回复 1 - 开通礼金\n" + + "回复 2 - 直接转链", + 1, wxid, false); } + } catch (Exception e) { + logger.error("处理礼金确认异常 - 用户: {}", wxid, e); + wxUtil.sendTextMessage(wxid, "处理请求时发生异常,请重试", 1, wxid, false); + state.reset(); } +} private void resetState(String wxid, UserInteractionState state) { state.reset(); saveState(INTERACTION_STATE_PREFIX + wxid, state); } - // 在发送提示信息时增加进度指示 - private void sendStepPrompt(String wxid, int step, int totalSteps) { - String progress = String.format("[%d/%d] ", step, totalSteps); - String message = progress + "请输入礼金金额(示例:20.50)"; - wxUtil.sendTextMessage(wxid, message, 1, wxid, false); - } - private void createPromotionWithGift(String fromWxid, String message) { - String key = INTERACTION_STATE_PREFIX + fromWxid; - UserInteractionState state = userInteractionStates.get(key); -// 修改createPromotionWithGift方法中的校验逻辑 - if (!state.validateStep(STEP_CONFIRM_GIFT)) { - logger.warn("状态校验失败,预期步骤:{} 实际步骤:{}", STEP_CONFIRM_GIFT, state.getCurrentStep()); - wxUtil.sendTextMessage(fromWxid, "流程顺序异常,请重新开始", 1, fromWxid, false); - return; - } -// 修改点3:在createPromotionWithGift方法开始处增加状态校验 - if (state == null || state.getCurrentStep() == null) { - logger.warn("非法状态访问: {}", fromWxid); - wxUtil.sendTextMessage(fromWxid, "⚠️ 会话超时,请重新开始流程", 1, fromWxid, false); - return; - } else { - LocalDateTime now = LocalDateTime.now(); - LocalDateTime lastInteractionTime = LocalDateTime.parse(state.getLastInteractionTime(), DATE_TIME_FORMATTER); - if (ChronoUnit.MINUTES.between(lastInteractionTime, now) > TIMEOUT_MINUTES) { - userInteractionStates.remove(key); - logger.debug("Deleted timeout state for user: {}", fromWxid); - state = new UserInteractionState(); - } - } - state.updateLastInteractionTime(); - userInteractionStates.put(key, state); // 确保状态保存 - - try { - switch (state.getCurrentStep()) { - case STEP_CONFIRM_GIFT: - if ("1".equals(message)) { - state.setCurrentStep(STEP_AMOUNT); - wxUtil.sendTextMessage(fromWxid, "请输入开通金额(元):", 1, fromWxid, false); - } else if ("2".equals(message)) { - // 不开通礼金,直接生成转链 - String cachedData = cacheMap.get("productData" + fromWxid); - if (cachedData != null) { - JSONObject jsonObject = JSONObject.parseObject(cachedData); - String skuId = jsonObject.getString("materialUrl"); - String transferUrl = transfer(skuId, null); - wxUtil.sendTextMessage(fromWxid, "转链后的链接:\n" + transferUrl, 1, fromWxid, false); - } else { - wxUtil.sendTextMessage(fromWxid, "未找到缓存的商品链接,请重新开始流程", 1, fromWxid, false); - } - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - } else { - wxUtil.sendTextMessage(fromWxid, "无效的选择,请重新输入:\n回复 1 - 是\n回复 2 - 否", 1, fromWxid, false); - } - break; - - case STEP_AMOUNT: - logger.debug("用户 {} 输入金额:{}", fromWxid, message); - if (message == null || message.trim().isEmpty()) { - wxUtil.sendTextMessage(fromWxid, "金额不能为空,请输入数字(如:100.00)", 1, fromWxid, false); - return; - } - if (!isValidAmount(message)) { - wxUtil.sendTextMessage(fromWxid, "金额格式错误,请输入数字(如:100.00)", 1, fromWxid, false); - return; - } - double amount = Double.parseDouble(message); - String formattedAmount = String.format("%.2f", amount); - state.getCollectedFields().put("amount", formattedAmount); - state.setCurrentStep(STEP_QUANTITY); - userInteractionStates.put(key, state); // ▼▼▼ 保存点2 ▼▼▼ - wxUtil.sendTextMessage(fromWxid, "请输入数量(1-100):", 1, fromWxid, false); - sendStepPrompt(fromWxid, 1, 3); - break; - - case STEP_QUANTITY: - logger.debug("用户 {} 输入数量:{}", fromWxid, message); // 新增 - if (!isValidQuantity(message)) { - wxUtil.sendTextMessage(fromWxid, "数量格式错误,请输入整数", 1, fromWxid, false); - return; - } - - int quantity = Integer.parseInt(message); - if (quantity < 1 || quantity > 100) { - wxUtil.sendTextMessage(fromWxid, "数量需在1-100之间", 1, fromWxid, false); - return; - } - - // 从缓存中获取 amount - String amountStr = state.getCollectedFields().get("amount"); - if (amountStr == null || amountStr.trim().isEmpty()) { - wxUtil.sendTextMessage(fromWxid, "未找到金额,请重新开始流程", 1, fromWxid, false); - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - return; - } - amount = Double.parseDouble(amountStr); - - logger.debug("礼金参数准备完成:金额={}元,数量={}", amount, quantity); // 新增 - - String cachedData = cacheMap.get("productData" + fromWxid); - String finalWenAn = cacheMap.get("finalWenAn" + fromWxid); - if (cachedData != null) { - JSONObject jsonObject = JSONObject.parseObject(cachedData); - String skuId = jsonObject.getString("materialUrl"); - String owner = jsonObject.getString("owner"); - String skuName = jsonObject.getString("skuName"); - - String giftKey = createGiftCoupon(skuId, amount, quantity, owner, skuName); - if (giftKey == null) { - logger.error("用户 {} 礼金创建失败:SKU={}, 金额={}元,数量={}", fromWxid, skuId, amount, quantity); // 新增 - wxUtil.sendTextMessage(fromWxid, "❌ 礼金创建失败,请检查商品是否符合要求", 1, fromWxid, false); - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - - return; - } - - logger.info("用户 {} 礼金创建成功:批次ID={}, 参数:SKU={}, 金额={}元,数量={}", fromWxid, giftKey, skuId, amount, quantity); // 新增关键成功日志 - state.getCollectedFields().put("giftKey", giftKey); - - // 生成转链 - String transferUrl = transfer(skuId, giftKey); - wxUtil.sendTextMessage(fromWxid, "附带礼金的链接:\n" + transferUrl, 1, fromWxid, false); - - wxUtil.sendTextMessage(fromWxid, "附带礼金的方案:\n" + finalWenAn.replaceAll(jsonObject.getString("url"), transferUrl), 1, fromWxid, true); - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - } else { - wxUtil.sendTextMessage(fromWxid, "未找到缓存的商品链接,请重新开始流程", 1, fromWxid, false); - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - } - break; - - default: - state.setCurrentStep(STEP_CONFIRM_GIFT); - wxUtil.sendTextMessage(fromWxid, "是否需要开通礼金?\n回复 1 - 是\n回复 2 - 否", 1, fromWxid, false); - break; - } - } catch (Exception e) { - logger.error("转链和礼金流程异常,用户 {} 当前步骤:{}", fromWxid, state.getCurrentStep(), e); - wxUtil.sendTextMessage(fromWxid, "❌ 系统异常,请稍后重试", 1, fromWxid, false); - state.reset(); - userInteractionStates.put(key, state); // 在外部保存 - } - } /** * 生成转链和方案的方法 @@ -1156,371 +1154,97 @@ public class JDUtil { * @param message 方案内容,包含商品链接 * @return 处理后的方案,附带商品信息 */ - public HashMap> generatePromotionContent(String message) { - HashMap> finallMessage = new HashMap<>(); - List textList = new ArrayList<>(); - List imagesList = new ArrayList<>(); - List dataList = new ArrayList<>(); - // 最终的方案 - List finalWenAn = new ArrayList<>(); - - - // 提取方案中的所有 u.jd.com 链接 - List urls = extractUJDUrls(message); - if (urls.isEmpty()) { - textList.add("方案中未找到有效的商品链接,请检查格式是否正确。"); - finallMessage.put("text", textList); - return finallMessage; - } - - - /** - * { - * "jd_union_open_goods_query_responce": { - * "code": "0", - * "queryResult": { - * "code": 200, - * "data": [ - * { - * "brandCode": "16407", - * "brandName": "松下(Panasonic)", - * "categoryInfo": { - * "cid1": 737, - * "cid1Name": "家用电器", - * "cid2": 794, - * "cid2Name": "大 家 电", - * "cid3": 880, - * "cid3Name": "洗衣机" - * }, - * "comments": 10000, - * "commissionInfo": { - * "commission": 599.95, - * "commissionShare": 5, - * "couponCommission": 592.95, - * "endTime": 1743609599000, - * "isLock": 1, - * "plusCommissionShare": 5, - * "startTime": 1742486400000 - * }, - * "couponInfo": { - * "couponList": [ - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 100, - * "getEndTime": 1746028799000, - * "getStartTime": 1743436800000, - * "isBest": 1, - * "isInputCoupon": 1, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoeVJzBK6Q6mfry4nz4ylRYHXsp_NnipDSrReNwGZGTxXhj94SGi9SkzR_7xaWEXLpO2boqow", - * "platformType": 0, - * "quota": 5000, - * "useEndTime": 1746028799000, - * "useStartTime": 1743436800000 - * }, - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 50, - * "getEndTime": 1746028799000, - * "getStartTime": 1743436800000, - * "hotValue": 0, - * "isBest": 0, - * "isInputCoupon": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoervD9YaNNXlsj6OBbZoWSFI1sZXw31PSjK04AH6tFP_Iu0YJlePWBT6sZfNvp14W0QK2K6A", - * "platformType": 0, - * "quota": 5000, - * "useEndTime": 1746028799000, - * "useStartTime": 1743436800000 - * }, - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 40, - * "getEndTime": 1746028799000, - * "getStartTime": 1743436800000, - * "hotValue": 0, - * "isBest": 0, - * "isInputCoupon": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoeqQdmhZbv1TiAn0QqI5gnT4g_zAgV5887llN8j6TatV-zpDfReipMr-hKkwQasE9NNUV2uQ", - * "platformType": 0, - * "quota": 500, - * "useEndTime": 1746028799000, - * "useStartTime": 1743436800000 - * }, - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 20, - * "getEndTime": 1746028799000, - * "getStartTime": 1743436800000, - * "hotValue": 0, - * "isBest": 0, - * "isInputCoupon": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoepukjRCuLpbwceODRbBw5HpNLRTVe5Olp99d34Izdo0s9lDtTIdyYZ-uJRCEXnc5N3OZ5LA", - * "platformType": 0, - * "quota": 2000, - * "useEndTime": 1746028799000, - * "useStartTime": 1743436800000 - * }, - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 10, - * "getEndTime": 1746028799000, - * "getStartTime": 1743436800000, - * "hotValue": 0, - * "isBest": 0, - * "isInputCoupon": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoeKIIbuvk-VsfJj_m1o3PRHqRaEBIbXHwooEMMt3z44T3cNQTkQsS8TjGnEeIz1obKp_t_mQ", - * "platformType": 0, - * "quota": 1000, - * "useEndTime": 1746028799000, - * "useStartTime": 1743436800000 - * } - * ] - * }, - * "deliveryType": 1, - * "eliteType": [], - * "forbidTypes": [ - * 0 - * ], - * "goodCommentsShare": 99, - * "imageInfo": { - * "imageList": [ - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/273873/17/14072/113544/67ebd215Feef3f56b/fc5156bf59a25ba3.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/273802/16/14273/84419/67ebd224F72dbcc8d/8ffe6f99aeeeb8fd.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/278931/40/12819/81341/67ea0227F41ffc604/ab1c6727e5d4f224.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/276989/12/13440/79310/67ea0226F68c2ed40/8acdeda05aa3596b.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/284503/25/12384/59498/67ea0225F8be60c83/b29ea34abc64346e.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/284667/29/12481/56118/67ea0225F97d9c729/f4c81d77064957bd.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/270959/35/13852/50552/67ea0224F911b8f00/248f9a7751549db7.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/274981/3/13326/48019/67ea0224Fe64bca69/b062218fc8db9b29.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/283691/1/12478/82267/67ea0223Fd4ecb0f5/2c32de327d8aa440.jpg" - * }, - * { - * "url": "https://img14.360buyimg.com/pop/jfs/t1/281457/31/12476/94335/67ea0222Fde76593a/cdddcd59b0b20c9a.jpg" - * } - * ] - * }, - * "inOrderComm30Days": 633170.8, - * "inOrderCount30Days": 3000, - * "inOrderCount30DaysSku": 100, - * "isHot": 1, - * "isJdSale": 1, - * "isOversea": 0, - * "itemId": "BsrqLq5CfIziE7BSl3ItPp8q_3DFaNVYJqfkRRLc7HR", - * "jxFlags": [], - * "materialUrl": "jingfen.jd.com/detail/BsrqLq5CfIziE7BSl3ItPp8q_3DFaNVYJqfkRRLc7HR.html", - * "oriItemId": "BMrqLq5CfIz9X04KC3ItPp8q_3DFaNVYJqfkRRLc7HR", - * "owner": "g", - * "pinGouInfo": {}, - * "pingGouInfo": {}, - * "priceInfo": { - * "lowestCouponPrice": 11899, - * "lowestPrice": 11999, - * "lowestPriceType": 1, - * "price": 11999 - * }, - * "purchasePriceInfo": { - * "basisPriceType": 1, - * "code": 200, - * "couponList": [ - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 100, - * "isBest": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoeVJzBK6Q6mfry4nz4ylRYHXsp_NnipDSrReNwGZGTxXhj94SGi9SkzR_7xaWEXLpO2boqow", - * "platformType": 0, - * "quota": 5000 - * }, - * { - * "bindType": 1, - * "couponStatus": 0, - * "couponStyle": 0, - * "discount": 40, - * "isBest": 0, - * "link": "https://coupon.m.jd.com/coupons/show.action?linkKey=AAROH_xIpeffAs_-naABEFoeqQdmhZbv1TiAn0QqI5gnT4g_zAgV5887llN8j6TatV-zpDfReipMr-hKkwQasE9NNUV2uQ", - * "platformType": 0, - * "quota": 500 - * } - * ], - * "message": "success", - * "purchaseNum": 1, - * "purchasePrice": 11859, - * "thresholdPrice": 11999 - * }, - * "shopInfo": { - * "shopId": 1000001741, - * "shopLabel": "0", - * "shopLevel": 4.9, - * "shopName": "松下洗衣机京东自营旗舰店" - * }, - * "skuName": "松下(Panasonic)白月光4.0Ultra 洗烘套装 10kg滚筒洗衣机+变频热泵烘干机 除毛升级2.0 水氧SPA护理 8532N+8532NR", - * "skuTagList": [ - * { - * "index": 1, - * "name": "自营", - * "type": 11 - * }, - * { - * "index": 1, - * "name": "plus", - * "type": 6 - * }, - * { - * "index": 3, - * "name": "7天无理由退货", - * "type": 12 - * } - * ], - * "spuid": 100137629936, - * "videoInfo": {} - * } - * ], - * "message": "success", - * "requestId": "o_0b721560_m8yp5pqj_88394507", - * "totalCount": 1 - * } - * } - * } - * - * */ - - // 如果需要图片和SKU名称,则代表要把图片下载发过去,还有对应的skuName - StringBuilder couponInfo = new StringBuilder(); - ArrayList> resultList = new ArrayList<>(); - - for (String url : urls) { - try { - // 查询商品信息 - GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url); - if (productInfo == null || productInfo.getCode() != 200) { - couponInfo.append("链接查询失败:").append(url).append("\n"); - continue; - } - long totalCount = productInfo.getTotalCount(); - couponInfo.append("链接查询成功:\n").append(" ").append(url).append("\n"); - - if (totalCount == 0) { - couponInfo.append("链接类型:优惠券\n"); - } else { - couponInfo.append("链接类型:商品\n"); - - //"materialUrl": "jingfen.jd.com/detail/BsrqLq5CfIziE7BSl3ItPp8q_3DFaNVYJqfkRRLc7HR.html", - //"oriItemId": "BMrqLq5CfIz9X04KC3ItPp8q_3DFaNVYJqfkRRLc7HR", - //"owner": "g", - //"shopInfo": { - // "shopId": 1000001741, - // "shopLabel": "0", - // "shopLevel": 4.9, - // "shopName": "松下洗衣机京东自营旗舰店" - //}, - //"skuName": "松下(Panasonic)白月光4.0Ultra 洗烘套装 10kg滚筒洗衣机+变频热泵烘干机 除毛升级2.0 水氧SPA护理 8532N+8532NR", - //"spuid": 100137629936, - JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(productInfo.getData()[0])); - jsonObject.put("url", url); - dataList.add(JSONObject.toJSONString(jsonObject)); - finallMessage.put("data", dataList); - - HashMap itemMap = new HashMap<>(); - itemMap.put("url", url); - itemMap.put("materialUrl", productInfo.getData()[0].getMaterialUrl()); - itemMap.put("oriItemId", productInfo.getData()[0].getOriItemId()); - itemMap.put("owner", productInfo.getData()[0].getOwner()); - itemMap.put("shopId", String.valueOf(productInfo.getData()[0].getShopInfo().getShopId())); - itemMap.put("shopName", productInfo.getData()[0].getShopInfo().getShopName()); - itemMap.put("skuName", productInfo.getData()[0].getSkuName()); - String replaceAll = itemMap.get("skuName").replaceAll("国家", "").replaceAll("补贴", "").replaceAll("15%", "").replaceAll("20%", ""); - itemMap.put("spuid", String.valueOf(productInfo.getData()[0].getSpuid())); - itemMap.put("commission", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommission())); - itemMap.put("commissionShare", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommissionShare())); - //for (HashMap.Entry entry : itemMap.entrySet()) { - //couponInfo.append(" ").append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); - //} - couponInfo.append(" ").append("店铺:\n").append(itemMap.get("shopName")).append("\n").append(" 标题:\n").append(replaceAll).append("\n").append("自营 POP:\n").append(itemMap.get("owner").equals("g") ? " 自营 " : " POP ") - .append("\n 佣金:\n").append(itemMap.get("commission")).append("\n").append("佣金比例:\n").append(itemMap.get("commissionShare")); - - - //StringBuilder images = new StringBuilder(); - if (productInfo.getData()[0].getImageInfo() != null) { - //images.append(" ").append("图片信息:\n"); - //int index = 1; - for (UrlInfo image : productInfo.getData()[0].getImageInfo().getImageList()) { - //images.append("图片 ").append(index++).append("\n").append(image.getUrl()).append("\n"); - imagesList.add(image.getUrl()); - } - } - //textList.add(String.valueOf(images)); - resultList.add(itemMap); - - /*直接生成闲鱼的商品文案*/ - StringBuilder sb1 = new StringBuilder(); - // 新建格式好日期 - DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒"); - sb1.append("(教你买) ").append(replaceAll).append("\n").append(WENAN_FANAN.replaceAll("更新", dateFormat.format(new Date()) + "更新")); - //textList.add("闲鱼方案的文案:\n"); - textList.add(String.valueOf(sb1)); - StringBuilder sb2 = new StringBuilder(); - sb2.append(replaceAll).append("\n").append(WENAN_ZCXS); - //textList.add("闲鱼正常销售:\n"); - textList.add(String.valueOf(sb2)); - } - textList.add(String.valueOf(couponInfo)); - - - } catch (Exception e) { - logger.error("处理商品链接时发生异常:{}", url, e); - couponInfo.append(" 处理商品链接时发生异常:").append(url).append("\n"); - textList.add(String.valueOf(couponInfo)); - finallMessage.put("text", textList); - } - } - /** - * 因为在这里转链返回,没有什么意义,后面走转链不转链,会重新发方案 - * */ - StringBuilder wenan = new StringBuilder(); - // 完成转链后替换链接为u.jd.com链接,方案不修改就返回 - //for (HashMap stringStringHashMap : resultList) { - // String transferUrl = transfer(stringStringHashMap.get("materialUrl"), null); - // wenan = new StringBuilder(message.replace(stringStringHashMap.get("url"), transferUrl)); - //} - wenan = new StringBuilder().append(FANAN_COMMON).append(message); - //textList.add(String.valueOf(wenan)); - finalWenAn.add(String.valueOf(wenan)); - - - finallMessage.put("text", textList); - finallMessage.put("images", imagesList); - finallMessage.put("finalWenAn", finalWenAn); - return finallMessage; +public HashMap> generatePromotionContent(String message) { + HashMap> finalMessage = new HashMap<>(); + List textList = new ArrayList<>(); + List imagesList = new ArrayList<>(); + List dataList = new ArrayList<>(); + List finalWenAn = new ArrayList<>(); + // 提取方案中的所有 u.jd.com 链接 + List urls = extractUJDUrls(message); + if (urls.isEmpty()) { + textList.add("方案中未找到有效的商品链接,请检查格式是否正确。"); + finalMessage.put("text", textList); + return finalMessage; } + for (String url : urls) { + try { + // 查询商品信息 + GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url); + if (productInfo == null || productInfo.getCode() != 200) { + textList.add("链接查询失败:" + url); + continue; + } + + long totalCount = productInfo.getTotalCount(); + if (totalCount == 0) { + // 优惠券链接 + textList.add("链接类型:优惠券\n" + url); + } else { + // 商品链接 + JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(productInfo.getData()[0])); + jsonObject.put("url", url); + dataList.add(jsonObject.toJSONString()); + + HashMap itemMap = new HashMap<>(); + itemMap.put("url", url); + itemMap.put("materialUrl", productInfo.getData()[0].getMaterialUrl()); + itemMap.put("oriItemId", productInfo.getData()[0].getOriItemId()); + itemMap.put("owner", productInfo.getData()[0].getOwner()); + itemMap.put("shopId", String.valueOf(productInfo.getData()[0].getShopInfo().getShopId())); + itemMap.put("shopName", productInfo.getData()[0].getShopInfo().getShopName()); + String skuName = productInfo.getData()[0].getSkuName(); + String cleanedSkuName = skuName.replaceAll("国家", "").replaceAll("补贴", "").replaceAll("15%", "").replaceAll("20%", ""); + itemMap.put("skuName", cleanedSkuName); + itemMap.put("spuid", String.valueOf(productInfo.getData()[0].getSpuid())); + itemMap.put("commission", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommission())); + itemMap.put("commissionShare", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommissionShare())); + + StringBuilder couponInfo = new StringBuilder(); + couponInfo.append("店铺:").append(itemMap.get("shopName")).append("\n") + .append("标题:").append(cleanedSkuName).append("\n") + .append("自营 POP:").append(itemMap.get("owner").equals("g") ? " 自营 " : " POP ").append("\n") + .append("佣金:").append(itemMap.get("commission")).append("\n") + .append("佣金比例:").append(itemMap.get("commissionShare")); + + textList.add(couponInfo.toString()); + + if (productInfo.getData()[0].getImageInfo() != null) { + for (UrlInfo image : productInfo.getData()[0].getImageInfo().getImageList()) { + imagesList.add(image.getUrl()); + } + } + + // 生成闲鱼的商品文案 + DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒"); + textList.add("(教你买) " + cleanedSkuName + "\n" + WENAN_FANAN.replaceAll("更新", dateFormat.format(new Date()) + "更新")); + + textList.add(cleanedSkuName + "\n" + WENAN_ZCXS); + } + } catch (Exception e) { + logger.error("处理商品链接时发生异常:{}", url, e); + textList.add("处理商品链接时发生异常:" + url); + } + } + + // 生成最终文案 + StringBuilder wenan = new StringBuilder(FANAN_COMMON); + for (String url : urls) { + wenan.append(message.replace(url, "")); + } + finalWenAn.add(wenan.toString()); + + finalMessage.put("text", textList); + finalMessage.put("images", imagesList); + finalMessage.put("data", dataList); + finalMessage.put("finalWenAn", finalWenAn); + + return finalMessage; +} + + private String downloadImage(String imageUrl, String destinationFile) { try (BufferedInputStream in = new BufferedInputStream(new URL(imageUrl).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(destinationFile)) { byte[] dataBuffer = new byte[1024];