From d8c3450426cfad72eff7330df8f50c823d1bfced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E6=AC=A7=EF=BC=88=E6=9E=97=E5=B9=B3=E5=87=A1?= =?UTF-8?q?=EF=BC=89?= Date: Wed, 26 Feb 2025 15:02:44 +0800 Subject: [PATCH] 1 --- .../java/cn/van/business/util/JDUtil.java | 145 +++++++++++++++--- .../van/business/util/WxMessageConsumer.java | 4 +- 2 files changed, 127 insertions(+), 22 deletions(-) diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index de74a83..1bec9bf 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -4,6 +4,7 @@ package cn.van.business.util; import cn.van.business.model.jd.OrderRow; import cn.van.business.repository.OrderRowRepository; import com.alibaba.fastjson2.util.DateUtils; +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.OrderService.request.query.OrderRowReq; @@ -29,10 +30,8 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; -import java.util.Comparator; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -77,9 +76,14 @@ public class JDUtil { private final OrderRowRepository orderRowRepository; private final WXUtil wxUtil; private final OrderUtil orderUtil; + // 在类中添加以下字段 + private final StringRedisTemplate redisTemplate; + private static final String INTERACTION_STATE_PREFIX = "interaction_state:"; + private static final long TIMEOUT_MINUTES = 1; + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - // 通过构造函数注入所有依赖项,Spring将自动注入这些依赖 - @Autowired // @Autowired 在构造函数上可以省略,如果类只有一个构造函数 + // 构造函数中注入StringRedisTemplate + @Autowired public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) { this.redisTemplate = redisTemplate; this.orderRowRepository = orderRowRepository; @@ -87,6 +91,27 @@ public class JDUtil { this.orderUtil = orderUtil; } + // 定义一个内部类来存储用户交互状态 + @Getter + @Setter + private static class UserInteractionState { + private String lastInteractionTime; + private String currentState; + + public UserInteractionState() { + this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); + this.currentState = "INIT"; + } + + public void updateLastInteractionTime() { + this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); + } + } + + // 添加ObjectMapper来序列化和反序列化UserInteractionState + private final ObjectMapper objectMapper = new ObjectMapper(); + + /** * 将 响应参数转化为 OrderRow,并返回 */ @@ -181,7 +206,7 @@ public class JDUtil { /** * 实时刷新最近10分钟的订单 */ - @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 + @Scheduled(cron = "0 * * * * ?") public void fetchLatestOrder() { LocalDateTime now = LocalDateTime.now(); LocalDateTime lastMinute = now.minusMinutes(10).withSecond(0).withNano(0); @@ -602,6 +627,8 @@ public class JDUtil { * 接收京粉指令指令 */ public void sendOrderToWxByOrderJD(String order, String fromWxid) { + + if ("消毒柜".equals(order)) { handleUserInteraction(fromWxid, order); return; } int[] param = {-1}; WXUtil.SuperAdmin superAdmin = super_admins.get(fromWxid); String unionId = superAdmin.getUnionId(); @@ -641,6 +668,7 @@ public class JDUtil { content.append("京高级违规+整数\r"); content.append("京高级+订单号\r\""); content.append("京高级SKU+sku\\r\""); + content.append("京高级搜索+搜索标题,只返回最近10条\r\""); break; case "测试指令": { //test01(); @@ -672,19 +700,7 @@ public class JDUtil { break; } case "昨日统计": { - List yesterdayOrders = filterOrdersByDate(orderRows, 1); - List todayOrders = filterOrdersByDate(orderRows, 0); - yesterdayOrders.removeAll(todayOrders); - content.append("昨日统计:\n"); - content.append("订单总数:").append(yesterdayOrders.size()).append("\r"); - content.append("已付款:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(yesterdayOrders).count()).append("\r"); - content.append("已付款佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(yesterdayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - break; + } case "三日统计": { List last3DaysOrders = filterOrdersByDate(orderRows, 3); @@ -1128,4 +1144,93 @@ public class JDUtil { private Long orderId; private Date orderDate; } + + /** + * + * 消毒柜部分的业务逻辑 + * + * + * */ + @Scheduled(fixedRate = 60000) // 每分钟执行一次 +public void cleanUpTimeoutStates() { + LocalDateTime now = LocalDateTime.now(); + Objects.requireNonNull(redisTemplate.keys(INTERACTION_STATE_PREFIX + "*")).forEach(key -> { + String stateJson = redisTemplate.opsForValue().get(key); + try { + UserInteractionState state = objectMapper.readValue(stateJson, UserInteractionState.class); + LocalDateTime lastInteractionTime = LocalDateTime.parse(state.getLastInteractionTime(), DATE_TIME_FORMATTER); + if (ChronoUnit.MINUTES.between(lastInteractionTime, now) > TIMEOUT_MINUTES) { + redisTemplate.delete(key); + } + } catch (Exception e) { + logger.error("Error parsing interaction state: " + e.getMessage()); + } + }); +} +public void handleUserInteraction(String fromWxid, String message) { + String key = INTERACTION_STATE_PREFIX + fromWxid; + String stateJson = redisTemplate.opsForValue().get(key); + UserInteractionState state; + if (stateJson == null) { + state = new UserInteractionState(); + } else { + try { + state = objectMapper.readValue(stateJson, UserInteractionState.class); + // 检查是否超时 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime lastInteractionTime = LocalDateTime.parse(state.getLastInteractionTime(), DATE_TIME_FORMATTER); + if (ChronoUnit.MINUTES.between(lastInteractionTime, now) > TIMEOUT_MINUTES) { + redisTemplate.delete(key); + state = new UserInteractionState(); + } + } catch (Exception e) { + logger.error("Error parsing interaction state: " + e.getMessage()); + state = new UserInteractionState(); + } + } + state.updateLastInteractionTime(); + + switch (state.getCurrentState()) { + case "INIT": + if ("消毒柜".equals(message)) { + wxUtil.sendTextMessage(fromWxid, "1,查询消毒柜订单;2,输入新的订单;3,修改订单", 1, fromWxid); + state.setCurrentState("DISINFECTANT_CABINET"); + } + break; + case "DISINFECTANT_CABINET": + switch (message) { + case "1": + // 查询消毒柜订单的逻辑 + wxUtil.sendTextMessage(fromWxid, "查询消毒柜订单的逻辑", 1, fromWxid); + state.setCurrentState("INIT"); + break; + case "2": + // 输入新的订单的逻辑 + wxUtil.sendTextMessage(fromWxid, "输入新的订单的逻辑", 1, fromWxid); + state.setCurrentState("INIT"); + break; + case "3": + // 修改订单的逻辑 + wxUtil.sendTextMessage(fromWxid, "修改订单的逻辑", 1, fromWxid); + state.setCurrentState("INIT"); + break; + default: + wxUtil.sendTextMessage(fromWxid, "无效的选择,请重新选择", 1, fromWxid); + break; + } + break; + default: + wxUtil.sendTextMessage(fromWxid, "无效的状态,请重新开始对话", 1, fromWxid); + state.setCurrentState("INIT"); + break; + } + + try { + redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(state), TIMEOUT_MINUTES, TimeUnit.MINUTES); + } catch (Exception e) { + logger.error("Error saving interaction state: " + e.getMessage()); + } +} + + } diff --git a/src/main/java/cn/van/business/util/WxMessageConsumer.java b/src/main/java/cn/van/business/util/WxMessageConsumer.java index 3c733e3..5c87e12 100644 --- a/src/main/java/cn/van/business/util/WxMessageConsumer.java +++ b/src/main/java/cn/van/business/util/WxMessageConsumer.java @@ -191,7 +191,7 @@ public class WxMessageConsumer { //} private static String getUrlStr(String msg) { //String urlPattern = "https?://[\\w-\\.]+(\\.[a-z]{2,})?(/[\\w-./?%&=]*)?" - String urlPattern = "https?://[^\\s]+?\\.(html|htm)(\\?[^\\s]*?)?"; + String urlPattern = "https?://\\S+?\\.(html|htm)(\\?\\S*?)?"; Pattern pattern = Pattern.compile(urlPattern); Matcher matcher = pattern.matcher(msg); @@ -207,7 +207,7 @@ public class WxMessageConsumer { // 移除最后一个字符(即问号) finallyUrl = finallyUrl.substring(0, finallyUrl.length() - 1); } - if (finallyUrl.contains("item.m.jd.com/product")) { + if (finallyUrl != null && finallyUrl.contains("item.m.jd.com/product")) { finallyUrl = finallyUrl.replace("item.m.jd.com/product", "item.jd.com"); } return finallyUrl;