1
This commit is contained in:
@@ -4,6 +4,7 @@ package cn.van.business.util;
|
|||||||
import cn.van.business.model.jd.OrderRow;
|
import cn.van.business.model.jd.OrderRow;
|
||||||
import cn.van.business.repository.OrderRowRepository;
|
import cn.van.business.repository.OrderRowRepository;
|
||||||
import com.alibaba.fastjson2.util.DateUtils;
|
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.DefaultJdClient;
|
||||||
import com.jd.open.api.sdk.JdClient;
|
import com.jd.open.api.sdk.JdClient;
|
||||||
import com.jd.open.api.sdk.domain.kplunion.OrderService.request.query.OrderRowReq;
|
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.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.Date;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -77,9 +76,14 @@ public class JDUtil {
|
|||||||
private final OrderRowRepository orderRowRepository;
|
private final OrderRowRepository orderRowRepository;
|
||||||
private final WXUtil wxUtil;
|
private final WXUtil wxUtil;
|
||||||
private final OrderUtil orderUtil;
|
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将自动注入这些依赖
|
// 构造函数中注入StringRedisTemplate
|
||||||
@Autowired // @Autowired 在构造函数上可以省略,如果类只有一个构造函数
|
@Autowired
|
||||||
public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) {
|
public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) {
|
||||||
this.redisTemplate = redisTemplate;
|
this.redisTemplate = redisTemplate;
|
||||||
this.orderRowRepository = orderRowRepository;
|
this.orderRowRepository = orderRowRepository;
|
||||||
@@ -87,6 +91,27 @@ public class JDUtil {
|
|||||||
this.orderUtil = orderUtil;
|
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,并返回
|
* 将 响应参数转化为 OrderRow,并返回
|
||||||
*/
|
*/
|
||||||
@@ -181,7 +206,7 @@ public class JDUtil {
|
|||||||
/**
|
/**
|
||||||
* 实时刷新最近10分钟的订单
|
* 实时刷新最近10分钟的订单
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
|
@Scheduled(cron = "0 * * * * ?")
|
||||||
public void fetchLatestOrder() {
|
public void fetchLatestOrder() {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
LocalDateTime lastMinute = now.minusMinutes(10).withSecond(0).withNano(0);
|
LocalDateTime lastMinute = now.minusMinutes(10).withSecond(0).withNano(0);
|
||||||
@@ -602,6 +627,8 @@ public class JDUtil {
|
|||||||
* 接收京粉指令指令
|
* 接收京粉指令指令
|
||||||
*/
|
*/
|
||||||
public void sendOrderToWxByOrderJD(String order, String fromWxid) {
|
public void sendOrderToWxByOrderJD(String order, String fromWxid) {
|
||||||
|
|
||||||
|
if ("消毒柜".equals(order)) { handleUserInteraction(fromWxid, order); return; }
|
||||||
int[] param = {-1};
|
int[] param = {-1};
|
||||||
WXUtil.SuperAdmin superAdmin = super_admins.get(fromWxid);
|
WXUtil.SuperAdmin superAdmin = super_admins.get(fromWxid);
|
||||||
String unionId = superAdmin.getUnionId();
|
String unionId = superAdmin.getUnionId();
|
||||||
@@ -641,6 +668,7 @@ public class JDUtil {
|
|||||||
content.append("京高级违规+整数\r");
|
content.append("京高级违规+整数\r");
|
||||||
content.append("京高级+订单号\r\"");
|
content.append("京高级+订单号\r\"");
|
||||||
content.append("京高级SKU+sku\\r\"");
|
content.append("京高级SKU+sku\\r\"");
|
||||||
|
content.append("京高级搜索+搜索标题,只返回最近10条\r\"");
|
||||||
break;
|
break;
|
||||||
case "测试指令": {
|
case "测试指令": {
|
||||||
//test01();
|
//test01();
|
||||||
@@ -672,19 +700,7 @@ public class JDUtil {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "昨日统计": {
|
case "昨日统计": {
|
||||||
List<OrderRow> yesterdayOrders = filterOrdersByDate(orderRows, 1);
|
|
||||||
List<OrderRow> 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 "三日统计": {
|
case "三日统计": {
|
||||||
List<OrderRow> last3DaysOrders = filterOrdersByDate(orderRows, 3);
|
List<OrderRow> last3DaysOrders = filterOrdersByDate(orderRows, 3);
|
||||||
@@ -1128,4 +1144,93 @@ public class JDUtil {
|
|||||||
private Long orderId;
|
private Long orderId;
|
||||||
private Date orderDate;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ public class WxMessageConsumer {
|
|||||||
//}
|
//}
|
||||||
private static String getUrlStr(String msg) {
|
private static String getUrlStr(String msg) {
|
||||||
//String urlPattern = "https?://[\\w-\\.]+(\\.[a-z]{2,})?(/[\\w-./?%&=]*)?"
|
//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);
|
Pattern pattern = Pattern.compile(urlPattern);
|
||||||
Matcher matcher = pattern.matcher(msg);
|
Matcher matcher = pattern.matcher(msg);
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ public class WxMessageConsumer {
|
|||||||
// 移除最后一个字符(即问号)
|
// 移除最后一个字符(即问号)
|
||||||
finallyUrl = finallyUrl.substring(0, finallyUrl.length() - 1);
|
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");
|
finallyUrl = finallyUrl.replace("item.m.jd.com/product", "item.jd.com");
|
||||||
}
|
}
|
||||||
return finallyUrl;
|
return finallyUrl;
|
||||||
|
|||||||
Reference in New Issue
Block a user