diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index bde1fa7..050630d 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -93,10 +93,10 @@ public class JDUtil { // Getter 方法,方便外部访问 @Getter @Value("${isRunning.wx}") - private String isRunning_wx ; + private String isRunning_wx; @Getter @Value("${isRunning.jd}") - private String isRunning_jd ; + private String isRunning_jd; // 构造函数中注入StringRedisTemplate @@ -489,21 +489,31 @@ public class JDUtil { content.append("一个月统计\r"); content.append("两个月统计\r"); content.append("三个月统计\r"); - content.append("总统计\r"); + content.append("总统计\r\n"); content.append("这个月统计\r"); - content.append("上个月统计\r"); + content.append("上个月统计\r\n"); + + content.append("今日订单\r"); content.append("昨日订单\r"); + content.append("七日订单\r"); content.append("刷新7天\r"); contents.add(content); content = new StringBuilder(); - content.append("高级菜单:京+高级+命令 \n 如: 京高级违规30\r"); + content.append("高级菜单:京+高级+命令 \n 如: 京高级违规30\r"); content.append("京高级违规+整数(不传数字为365天)\r"); content.append("京高级SKU+sku\r"); content.append("京高级搜索+搜索标题(精准查询订单号+精准查询sku+模糊查询收件人+模糊查询地址),只返回最近100条\r"); + contents.add(content); + + content = new StringBuilder(); + + content.append("礼金\r"); + content.append("转链\r"); + contents.add(content); break; case "测试指令": { @@ -528,22 +538,21 @@ public class JDUtil { contents.add(content); break; } - case "已付款": { + case "昨日统计": { content = new StringBuilder(); - - List yfkOrders = orderRows.stream().filter(orderRow -> orderRow.getValidCode() == 16).collect(Collectors.toList()); - content.append("已付款:\n"); - content.append("订单总数:").append(yfkOrders.size()).append("\r"); - content.append("佣金总数:").append(yfkOrders.stream().mapToDouble(OrderRow::getEstimateFee).sum()); - for (OrderRow orderRow : yfkOrders) { - orderUtil.orderToWx(orderRow, false); - } + List yesterdayOrders = filterOrdersByDate(orderRows, 1); + 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()); contents.add(content); break; - } - case "昨日统计": { - } case "三日统计": { content = new StringBuilder(); @@ -705,8 +714,9 @@ public class JDUtil { content.append("已完成佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(todayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - for (OrderRow orderRow : todayOrders) { - orderUtil.orderToWx(orderRow, false); + + if(!todayOrders.isEmpty()){ + orderUtil.orderToWxBatch(todayOrders); } contents.add(content); @@ -727,8 +737,31 @@ public class JDUtil { 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()); - for (OrderRow orderRow : yesterdayOrders) { - orderUtil.orderToWx(orderRow, false); + + if(!yesterdayOrders.isEmpty()){ + orderUtil.orderToWxBatch(todayOrders); + } + + contents.add(content); + break; + } + case "七日订单": { + content = new StringBuilder(); + List sevendayOrders = filterOrdersByDate(orderRows, 1); + List todayOrders = filterOrdersByDate(orderRows, 0); + sevendayOrders.removeAll(todayOrders); + content.append("昨日统计:\n"); + content.append("订单总数:").append(sevendayOrders.size()).append("\r"); + content.append("已付款:").append(sevendayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); + content.append("已取消:").append(sevendayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); + content.append("已完成:").append(sevendayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); + content.append("违规:").append(getStreamForWeiGui(sevendayOrders).count()).append("\r"); + content.append("已付款佣金:").append(sevendayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); + content.append("已完成佣金:").append(sevendayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); + content.append("\r" + "违规佣金:").append(getStreamForWeiGui(sevendayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); + + if(!sevendayOrders.isEmpty()){ + orderUtil.orderToWxBatch(todayOrders); } contents.add(content); @@ -813,12 +846,8 @@ public class JDUtil { content.append(daysInt).append("天").append("\r\n"); - Map skuIdViolationCountMap = filterOrdersByDays.stream() - .filter(orderRow -> orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28).filter(orderRow -> orderRow.getSkuName() != null) - .collect(Collectors.groupingBy( - OrderRow::getSkuName, // ✅ 拼接SKU - Collectors.counting() - )); + Map skuIdViolationCountMap = filterOrdersByDays.stream().filter(orderRow -> orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28).filter(orderRow -> orderRow.getSkuName() != null).collect(Collectors.groupingBy(OrderRow::getSkuName, // ✅ 拼接SKU + Collectors.counting())); Map> orderInfoMap = filterOrdersByDays.stream().filter(orderRow -> orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28).filter(orderRow -> orderRow.getSkuName() != null).map(orderRow -> { OrderInfo info = new OrderInfo(); info.setSkuName(orderRow.getSkuName()); @@ -1145,6 +1174,7 @@ public class JDUtil { productOrderRepository.save(productOrder); logger.debug("Saved product order: {}", productOrder); } + // 新增礼金流程处理方法 private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) { if ("京礼金".equals(message)) { @@ -1160,14 +1190,10 @@ public class JDUtil { String skuId = parseSkuFromUrl(message); Map productInfo = queryProductInfo(skuId); state.getCollectedFields().put("skuId", skuId); - state.getCollectedFields().put("productInfo", - productInfo.get("name") + "\n价格:" + productInfo.get("price")); + state.getCollectedFields().put("productInfo", productInfo.get("name") + "\n价格:" + productInfo.get("price")); state.setCurrentStep(STEP_AMOUNT); - wxUtil.sendTextMessage(fromWxid, - "商品信息:\n" + productInfo.get("name") + - "\n当前价格:" + productInfo.get("price") + - "\n请输入开通金额(元):", 1, fromWxid); + wxUtil.sendTextMessage(fromWxid, "商品信息:\n" + productInfo.get("name") + "\n当前价格:" + productInfo.get("price") + "\n请输入开通金额(元):", 1, fromWxid); break; case STEP_AMOUNT: @@ -1188,11 +1214,7 @@ public class JDUtil { state.getCollectedFields().put("quantity", message); // 调用开通接口 - boolean result = activateGiftMoney( - state.getCollectedFields().get("skuId"), - Double.parseDouble(state.getCollectedFields().get("amount")), - Integer.parseInt(message) - ); + boolean result = activateGiftMoney(state.getCollectedFields().get("skuId"), Double.parseDouble(state.getCollectedFields().get("amount")), Integer.parseInt(message)); String response = result ? "开通成功!" : "开通失败,请稍后重试"; wxUtil.sendTextMessage(fromWxid, response, 1, fromWxid); @@ -1219,22 +1241,20 @@ public class JDUtil { // 实现实际的开通接口调用 return true; } + // 定义一个内部类来存储用户交互状态 @Getter @Setter static class UserInteractionState { // 推荐使用枚举管理状态 public enum ProcessState { - INIT, - GIFT_MONEY_FLOW, - DISINFECTANT_CABINET + INIT, GIFT_MONEY_FLOW, DISINFECTANT_CABINET } public enum GiftMoneyStep { - STEP_PRODUCT_LINK, - STEP_AMOUNT, - STEP_QUANTITY + STEP_PRODUCT_LINK, STEP_AMOUNT, STEP_QUANTITY } + private GiftMoneyStep currentStep; // 新增当前步骤字段 private String lastInteractionTime; @@ -1253,6 +1273,7 @@ public class JDUtil { public void updateLastInteractionTime() { this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); } + // UserInteractionState类缺少reset方法 public void reset() { this.currentState = INIT; @@ -1262,12 +1283,14 @@ public class JDUtil { } } + // 增强京东链接解析的正则表达式 private String parseSkuFromUrl(String url) { Pattern pattern = Pattern.compile("/(\\d+)(\\.html|\\?)"); // 支持更多链接格式 Matcher matcher = pattern.matcher(url); return matcher.find() ? matcher.group(1) : null; } + // 改进金额验证提示 private boolean isValidAmount(String input) { String fromWxid = ""; @@ -1277,6 +1300,7 @@ public class JDUtil { } return true; } + // 限流异常类(需自定义) public static class RateLimitExceededException extends RuntimeException { public RateLimitExceededException(String message) { diff --git a/src/main/java/cn/van/business/util/OrderUtil.java b/src/main/java/cn/van/business/util/OrderUtil.java index c2bc47f..094e023 100644 --- a/src/main/java/cn/van/business/util/OrderUtil.java +++ b/src/main/java/cn/van/business/util/OrderUtil.java @@ -11,6 +11,7 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; +import java.util.List; import static cn.van.business.util.WXUtil.getWxidFromJdid; @@ -51,7 +52,7 @@ public class OrderUtil { // 当 isAutoFlush 为 false 或状态确实有变化时,进行消息发送 String content = getFormattedOrderInfo(orderRow, lastValidCode); String wxId = getWxidFromJdid(orderRow.getUnionId().toString()); - if (Util.isNotEmpty(wxId)){ + if (Util.isNotEmpty(wxId)) { wxUtil.sendTextMessage(wxId, content, 1, wxId); } } @@ -63,36 +64,62 @@ public class OrderUtil { } /** - * 将数据库订单转化成微信所需要文本 + * 手动调用 将订单发送到微信 批量 */ - public String getFormattedOrderInfo(OrderRow orderRow, Integer oldValidCode) { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - ValidCodeConverter converter = new ValidCodeConverter(); - String orderInfo = - //+ "订单+sku:" + orderRow.getId() + "\r" - "订单:" + orderRow.getOrderId() + " (" + (orderRow.getPlus() == 1 ? "plus" : "非plus") + ")\r" + + @Async("threadPoolTaskExecutor") + public void orderToWxBatch(List orderRowList) { + if (!orderRowList.isEmpty()) { + String wxId = getWxidFromJdid(orderRowList.get(0).getUnionId().toString()); + StringBuilder content = new StringBuilder(); + for (OrderRow orderRow : orderRowList) { + String oldValidCode = redisTemplate.opsForValue().get(ORDER_ROW_KEY + orderRow.getId()); - "状态:" + (converter.getCodeDescription(orderRow.getValidCode())) + "\r" + // 检查Redis中是否有旧的状态码,没有的话赋予默认值 + Integer lastValidCode = oldValidCode != null ? Integer.parseInt(oldValidCode) : -100; + content.append(getFormattedOrderInfo(orderRow, lastValidCode)); - + "名称:" + orderRow.getSkuName() + "\r\n" - //+ "商品单价:" + orderRow.getPrice() + "\r" - //+ "商品数量:" + orderRow.getSkuNum() + "\r" - //+ "商品总价:" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r" - + "计佣金额:" + orderRow.getEstimateCosPrice() + "\r" + } + if (Util.isNotEmpty(wxId)) { + wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId); + } - //+ "金额:" + orderRow.getActualCosPrice() + "\r" - + "比例:" + orderRow.getCommissionRate() + "\r" - + "佣金:" + orderRow.getEstimateFee() + "\r\n" - - + "下单:" + formatter.format(orderRow.getOrderTime()) + "\r" - + "完成:" + (orderRow.getFinishTime() != null ? formatter.format(orderRow.getFinishTime()) : "未完成") + "\r"; - if (oldValidCode != -100) { - if (!oldValidCode.equals(orderRow.getValidCode())) - orderInfo = "从 :" + (converter.getCodeDescription(oldValidCode)) + "\r变成 " + - (converter.getCodeDescription(orderRow.getValidCode())) + "\r\n" + orderInfo; } - - return orderInfo; } + + + +/** + * 将数据库订单转化成微信所需要文本 + */ +public String getFormattedOrderInfo(OrderRow orderRow, Integer oldValidCode) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + ValidCodeConverter converter = new ValidCodeConverter(); + String orderInfo = + //+ "订单+sku:" + orderRow.getId() + "\r" + "订单:" + orderRow.getOrderId() + " (" + (orderRow.getPlus() == 1 ? "plus" : "非plus") + ")\r" + + + "状态:" + (converter.getCodeDescription(orderRow.getValidCode())) + "\r" + + + "名称:" + orderRow.getSkuName() + "\r\n" + //+ "商品单价:" + orderRow.getPrice() + "\r" + //+ "商品数量:" + orderRow.getSkuNum() + "\r" + //+ "商品总价:" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r" + + "计佣金额:" + orderRow.getEstimateCosPrice() + "\r" + + //+ "金额:" + orderRow.getActualCosPrice() + "\r" + + "比例:" + orderRow.getCommissionRate() + "\r" + + "佣金:" + orderRow.getEstimateFee() + "\r\n" + + + "下单:" + formatter.format(orderRow.getOrderTime()) + "\r" + + "完成:" + (orderRow.getFinishTime() != null ? formatter.format(orderRow.getFinishTime()) : "未完成") + "\r"; + if (oldValidCode != -100) { + if (!oldValidCode.equals(orderRow.getValidCode())) + orderInfo = "从 :" + (converter.getCodeDescription(oldValidCode)) + "\r变成 " + + (converter.getCodeDescription(orderRow.getValidCode())) + "\r\n" + orderInfo; + } + + + return orderInfo; +} }