From c8efd8512e39afd56ef48f1d732b8e67f00dc894 Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 12 Apr 2025 14:28:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E7=B2=BE=E7=AE=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/van/business/util/JDUtil.java | 309 +----------------- 1 file changed, 6 insertions(+), 303 deletions(-) diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index 2138eb5..d146744 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -9,13 +9,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.jd.open.api.sdk.DefaultJdClient; import com.jd.open.api.sdk.JdClient; import com.jd.open.api.sdk.domain.kplunion.CouponService.request.get.CreateGiftCouponReq; -import com.jd.open.api.sdk.domain.kplunion.CouponService.request.stop.StopGiftCouponReq; -import com.jd.open.api.sdk.domain.kplunion.GoodsService.request.query.BigFieldGoodsReq; import com.jd.open.api.sdk.domain.kplunion.GoodsService.request.query.GoodsReq; -import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.BigfieldQueryResult; import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.GoodsQueryResult; import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.UrlInfo; -import com.jd.open.api.sdk.domain.kplunion.OrderService.request.query.OrderRowReq; import com.jd.open.api.sdk.domain.kplunion.promotionbysubunioni.PromotionService.request.get.PromotionCodeReq; import com.jd.open.api.sdk.request.kplunion.*; import com.jd.open.api.sdk.response.kplunion.*; @@ -29,10 +25,6 @@ import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.io.BufferedInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; @@ -140,7 +132,7 @@ public class JDUtil { public String convertAddress(String input) { try { // 正则表达式分解输入内容 - Pattern pattern = Pattern.compile("^(.+?)\\[(\\d+)\\]\\s+(\\d+)\\s+(.+)\\[\\d+\\]$"); + Pattern pattern = Pattern.compile("^(.+?)\\[(\\d+)\\]\\s+(\\d+)\\s+(.+)\\[\\d+]$"); Matcher matcher = pattern.matcher(input); if (matcher.matches()) { @@ -461,7 +453,7 @@ public class JDUtil { return info; }).collect(Collectors.groupingBy(OrderInfo::getSkuName)); - List> sortedViolationCounts = skuIdViolationCountMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()); + List> sortedViolationCounts = skuIdViolationCountMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).toList(); Integer num = 0; for (Map.Entry entry : sortedViolationCounts) { @@ -576,48 +568,12 @@ public class JDUtil { } } - /** - * 获取订单列表 - * - * @param start 开始时间 - * @param end 结束时间 - * @return - * @throws Exception - */ - public UnionOpenOrderRowQueryResponse getUnionOpenOrderRowQueryResponse(LocalDateTime start, LocalDateTime end, Integer pageIndex, String appKey, String secretKey) throws Exception { - String startTime = start.format(DATE_TIME_FORMATTER); - String endTime = end.format(DATE_TIME_FORMATTER); - // 模拟 API 调用 - //System.out.println("调用API - 从 " + startTime - // + " 到 " + endTime); - // 实际的 API 调用逻辑应在这里进行 - JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, appKey, secretKey); - UnionOpenOrderRowQueryRequest request = new UnionOpenOrderRowQueryRequest(); - OrderRowReq orderReq = new OrderRowReq(); - orderReq.setPageIndex(pageIndex); - orderReq.setPageSize(200); - orderReq.setStartTime(startTime); - orderReq.setEndTime(endTime); - orderReq.setType(1); - - - request.setOrderReq(orderReq); - request.setVersion("1.0"); - request.setSignmethod("md5"); - // 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8。API服务端允许客户端请求最大时间误差为10分钟 - Date date = new Date(); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - request.setTimestamp(simpleDateFormat.format(date)); - - - return client.execute(request); - } - /** * 接口描述:通过商品链接、领券链接、活动链接获取普通推广链接或优惠券二合一推广链接 * jd.union.open.promotion.bysubunionid.get */ String transfer(String url, String giftCouponKey) { + JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ); UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest(); @@ -668,22 +624,7 @@ public class JDUtil { return result; } -//public UnionOpenGoodsBigfieldQueryResponse getUnionOpenGoodsBigfieldQueryResponse(){ -// JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, APP_KEY, SECRET_KEY); -// -// UnionOpenGoodsBigfieldQueryRequest request=new UnionOpenGoodsBigfieldQueryRequest(); -// BigFieldGoodsReq goodsReq=new BigFieldGoodsReq(); -// goodsReq.setSkuIds(); -// request.setGoodsReq(goodsReq); -// request.setVersion("1.0"); -// UnionOpenGoodsBigfieldQueryResponse response= null; -// try { -// response = client.execute(request); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// return response; -//} + /** * 消毒柜部分的业务逻辑 @@ -958,155 +899,6 @@ public class JDUtil { 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); // 在外部保存 - } - } - /** * 生成转链和方案的方法 * @@ -1130,7 +922,6 @@ public class JDUtil { return finallMessage; } - /** * { * "jd_union_open_goods_query_responce": { @@ -1459,14 +1250,9 @@ public class JDUtil { /** * 因为在这里转链返回,没有什么意义,后面走转链不转链,会重新发方案 * */ - 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)); - //} + StringBuilder wenan; + wenan = new StringBuilder().append(FANAN_COMMON).append(message); - //textList.add(String.valueOf(wenan)); finalWenAn.add(String.valueOf(wenan)); @@ -1477,19 +1263,6 @@ public class JDUtil { } - 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]; - int bytesRead; - while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } - return destinationFile; - } catch (IOException e) { - logger.error("Error downloading image from URL: {}", imageUrl, e); - return null; - } - } /** * 提取方案中的所有 u.jd.com 链接 @@ -1552,46 +1325,6 @@ public class JDUtil { return queryResult; } - // 在JDUtil类中新增方法实现商品详情查询接口 - public UnionOpenGoodsBigfieldQueryResponse getUnionOpenGoodsBigfieldQueryResponse(String skuId) throws Exception { - JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ); - - UnionOpenGoodsBigfieldQueryRequest request = new UnionOpenGoodsBigfieldQueryRequest(); - BigFieldGoodsReq goodsReq = new BigFieldGoodsReq(); - goodsReq.setSkuIds(List.of(Long.parseLong(skuId)).toArray(new Long[0])); // 传入skuId集合 - /** - * 查询域集合,不填写则查询全部,目目前支持:categoryInfo(类目信息),imageInfo(图片信息), - * baseBigFieldInfo(基础大字段信息),bookBigFieldInfo(图书大字段信息), - * videoBigFieldInfo(影音大字段信息),detailImages(商详图)*/ - //goodsReq.setFields(new String[]{"categoryInfo", "imageInfo", "baseBigFieldInfo"}); // 设置需要查询的字段 - goodsReq.setSceneId(2); // 设置场景ID - - request.setGoodsReq(goodsReq); - request.setVersion("1.0"); - request.setSignmethod("md5"); - request.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); - - return client.execute(request); - } - - // 修改parseSkuFromUrl方法提取SKU - private String parseSkuFromUrl(String url) { - Matcher m = Pattern.compile("item.jd.com/(\\d+).html").matcher(url); - return m.find() ? m.group(1) : null; - } - - public BigfieldQueryResult queryProductInfo(String skuId) throws Exception { - UnionOpenGoodsBigfieldQueryResponse response = getUnionOpenGoodsBigfieldQueryResponse(skuId); - if (response == null || response.getQueryResult() == null) { - return null; - } - BigfieldQueryResult queryResult = response.getQueryResult(); - if (queryResult.getCode() != 200) { - return null; - } - - return queryResult; - } // 新增礼金创建方法 public String createGiftCoupon(String skuId, double amount, int quantity, String owner, String skuName) throws Exception { @@ -1662,28 +1395,6 @@ public class JDUtil { return null; } - // 修改activateGiftMoney方法调用真实接口 - private boolean activateGiftMoney(String skuId, double amount, int quantity, String owner) { - return false; - } - - // 新增礼金停止方法(可选) - public boolean stopGiftCoupon(String giftKey) throws Exception { - JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ); - - - UnionOpenCouponGiftStopRequest request = new UnionOpenCouponGiftStopRequest(); - StopGiftCouponReq couponReq = new StopGiftCouponReq(); - couponReq.setGiftCouponKey(giftKey); - - request.setCouponReq(couponReq); - request.setVersion("1.0"); - request.setSignmethod("md5"); - request.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); - - UnionOpenCouponGiftStopResponse response = client.execute(request); - return "200".equals(response.getCode()); - } boolean isValidAmount(String input) { // 新增:直接处理 null 或空字符串 @@ -1795,12 +1506,6 @@ public class JDUtil { return this.currentStep != null && this.currentStep.getCode() == expectedStep.getCode(); } - // 在UserInteractionState中增加恢复方法 - public void restoreState(Map backup) { - this.collectedFields.putAll(backup); - this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); - } - // 推荐使用枚举管理状态 public enum ProcessState { INIT, GIFT_MONEY_FLOW, PRODUCT_PROMOTION @@ -1819,10 +1524,8 @@ public class JDUtil { return code; } - } - } // 限流异常类(需自定义)