diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index 01a1540..fe531c3 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -17,6 +17,7 @@ import com.jd.open.api.sdk.request.kplunion.UnionOpenOrderRowQueryRequest; import com.jd.open.api.sdk.request.kplunion.UnionOpenPromotionBysubunionidGetRequest; import com.jd.open.api.sdk.response.kplunion.UnionOpenOrderRowQueryResponse; import com.jd.open.api.sdk.response.kplunion.UnionOpenPromotionBysubunionidGetResponse; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import org.slf4j.Logger; @@ -462,6 +463,22 @@ public class JDUtil { // 具体逻辑 } + private OrderStats calculateStats(List orders) { + long paid = orders.stream().filter(o -> o.getValidCode() == 16).count(); + long pending = orders.stream().filter(o -> o.getValidCode() == 15).count(); + long canceled = orders.stream().filter(o -> o.getValidCode() != 16 && o.getValidCode() != 17).count(); + long completed = orders.stream().filter(o -> o.getValidCode() == 17).count(); + + return new OrderStats(orders.size(), orders.size() - canceled, paid, orders.stream().filter(o -> o.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum(), pending, orders.stream().filter(o -> o.getValidCode() == 15).mapToDouble(OrderRow::getEstimateFee).sum(), canceled, completed, orders.stream().filter(o -> o.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum(), getStreamForWeiGui(orders).count(), getStreamForWeiGui(orders).mapToDouble(o -> o.getEstimateCosPrice() * o.getCommissionRate() * 0.01).sum()); + } + + private StringBuilder buildStatsContent(String title, OrderStats stats) { + StringBuilder content = new StringBuilder(); + content.append(title).append(":\n").append("订单总数:").append(stats.getTotalOrders()).append("\r").append("订单总数(不含取消):").append(stats.getValidOrders()).append("\r\n").append("已付款:").append(stats.getPaidOrders()).append("\r").append("已付款佣金:").append(stats.getPaidCommission()).append("\r\n").append("待付款:").append(stats.getPendingOrders()).append("\r") // 修正了原代码中的Stream未终止问题 + .append("待付款佣金:").append(stats.getPendingCommission()).append("\r\n").append("已取消:").append(stats.getCanceledOrders()).append("\r").append("已完成:").append(stats.getCompletedOrders()).append("\r").append("已完成佣金:").append(stats.getCompletedCommission()).append("\r").append("违规:").append(stats.getViolations()).append("\r").append("违规佣金:").append(stats.getViolationCommission()); + return content; + } + /** * 接收京粉指令指令 */ @@ -525,37 +542,18 @@ public class JDUtil { } case "今日统计": { content = new StringBuilder(); - - List todayOrders = filterOrdersByDate(orderRows, 0); // 订单总数,已付款,已取消,佣金总计 - content.append("今日统计:\n"); - content.append("订单总数:").append(todayOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(todayOrders.size() - todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已付款:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(todayOrders).count()).append("\r"); - content.append("已付款佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - 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()); - + List todayOrders = filterOrdersByDate(orderRows, 0); + OrderStats stats = calculateStats(todayOrders); + contents.add(buildStatsContent("今日统计", stats)); contents.add(content); break; } case "昨日统计": { content = new StringBuilder(); List yesterdayOrders = filterOrdersByDate(orderRows, 1); - content.append("昨日统计:\n"); - content.append("订单总数:").append(yesterdayOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(yesterdayOrders.size() - yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).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()); + OrderStats stats = calculateStats(yesterdayOrders); + contents.add(buildStatsContent("昨日统计", stats)); contents.add(content); break; @@ -563,17 +561,8 @@ public class JDUtil { case "三日统计": { content = new StringBuilder(); List last3DaysOrders = filterOrdersByDate(orderRows, 3); - content.append("三日统计:\n"); - content.append("订单总数:").append(last3DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last3DaysOrders.size() - last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last3DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last3DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last3DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); + OrderStats stats = calculateStats(last3DaysOrders); + contents.add(buildStatsContent("三日统计", stats)); contents.add(content); break; @@ -581,35 +570,16 @@ public class JDUtil { case "七日统计": { content = new StringBuilder(); List last7DaysOrders = filterOrdersByDate(orderRows, 7); - content.append("七日统计:\n"); - content.append("订单总数:").append(last7DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last7DaysOrders.size() - last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已付款:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last7DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last7DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(last7DaysOrders); + contents.add(buildStatsContent("七日统计", stats)); contents.add(content); break; } case "一个月统计": { content = new StringBuilder(); List last30DaysOrders = filterOrdersByDate(orderRows, 30); - content.append("一个月统计:\n"); - content.append("订单总数:").append(last30DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last30DaysOrders.size() - last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last30DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last30DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(last30DaysOrders); + contents.add(buildStatsContent("一个月统计", stats)); contents.add(content); break; } @@ -617,18 +587,8 @@ public class JDUtil { content = new StringBuilder(); List last60DaysOrders = filterOrdersByDate(orderRows, 60); - content.append("两个月统计:\n"); - content.append("订单总数:").append(last60DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last60DaysOrders.size() - last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last60DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last60DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(last60DaysOrders); + contents.add(buildStatsContent("两个月统计", stats)); contents.add(content); break; } @@ -636,17 +596,8 @@ public class JDUtil { content = new StringBuilder(); List last90DaysOrders = filterOrdersByDate(orderRows, 90); - content.append("订单总数:").append(last90DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last90DaysOrders.size() - last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last90DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last90DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(last90DaysOrders); + contents.add(buildStatsContent("三个月统计", stats)); contents.add(content); break; } @@ -656,19 +607,8 @@ public class JDUtil { // 计算出距离1号有几天 int days = LocalDate.now().getDayOfMonth(); List thisMonthOrders = filterOrdersByDate(orderRows, days); - - content.append("本月统计:\n"); - content.append("订单总数:").append(thisMonthOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(thisMonthOrders.size() - thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(thisMonthOrders).count()).append("\r"); - content.append("已付款佣金:").append(thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(thisMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(thisMonthOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(thisMonthOrders); + contents.add(buildStatsContent("这个月统计", stats)); contents.add(content); break; } @@ -682,18 +622,8 @@ public class JDUtil { List thisMonthOrders = filterOrdersByDate(orderRows, days); lastMonthOrders = lastMonthOrders.stream().filter(orderRow -> !thisMonthOrders.contains(orderRow)).collect(Collectors.toList()); - content.append("上个月统计:\n"); - content.append("订单总数:").append(lastMonthOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(lastMonthOrders.size() - lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(lastMonthOrders).count()).append("\r"); - content.append("已付款佣金:").append(lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(lastMonthOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(lastMonthOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(lastMonthOrders); + contents.add(buildStatsContent("上个月统计", stats)); contents.add(content); break; @@ -703,18 +633,8 @@ public class JDUtil { case "总统计": { content = new StringBuilder(); - content.append("总统计:\n"); - content.append("订单总数:").append(orderRows.size()).append("\r"); - content.append("订单总数(不含取消):").append(orderRows.size() - orderRows.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(orderRows.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(orderRows.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(orderRows.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(orderRows).count()).append("\r"); - content.append("已付款佣金:").append(orderRows.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(orderRows.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(orderRows).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); - + OrderStats stats = calculateStats(orderRows); + contents.add(buildStatsContent("总统计", stats)); contents.add(content); break; } @@ -725,19 +645,8 @@ public class JDUtil { content = new StringBuilder(); List todayOrders = filterOrdersByDate(orderRows, 0); // 订单总数,已付款,已取消,佣金总计 - content.append("今日统计:\n"); - content.append("订单总数:").append(todayOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(todayOrders.size() - todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - content.append("已付款:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(todayOrders).count()).append("\r"); - content.append("已付款佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - 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()); - - + OrderStats stats = calculateStats(todayOrders); + contents.add(buildStatsContent("今日统计", stats)); if (!todayOrders.isEmpty()) { orderUtil.orderToWxBatch(todayOrders); } @@ -751,18 +660,8 @@ public class JDUtil { 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.size() - yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).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()); - + OrderStats stats = calculateStats(yesterdayOrders); + contents.add(buildStatsContent("昨日统计", stats)); if (!yesterdayOrders.isEmpty()) { orderUtil.orderToWxBatch(todayOrders); } @@ -775,18 +674,8 @@ public class JDUtil { List last7DaysOrders = filterOrdersByDate(orderRows, 1); List todayOrders = filterOrdersByDate(orderRows, 0); last7DaysOrders.removeAll(todayOrders); - content.append("七日统计:\n"); - content.append("订单总数:").append(last7DaysOrders.size()).append("\r"); - content.append("订单总数(不含取消):").append(last7DaysOrders.size() - last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - - - content.append("已付款:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); - content.append("已取消:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); - content.append("已完成:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); - content.append("违规:").append(getStreamForWeiGui(last7DaysOrders).count()).append("\r"); - content.append("已付款佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); - content.append("已完成佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); - content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last7DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); + OrderStats stats = calculateStats(last7DaysOrders); + contents.add(buildStatsContent("七日统计", stats)); if (!last7DaysOrders.isEmpty()) { orderUtil.orderToWxBatch(last7DaysOrders); @@ -846,512 +735,495 @@ public class JDUtil { } } +/** + * 接收京粉指令指令 + * 高级菜单 + */ +public void sendOrderToWxByOrderJDAdvanced(String order, String fromWxid) { + int[] param = {-1}; + WXUtil.SuperAdmin superAdmin = super_admins.get(fromWxid); + String unionId = superAdmin.getUnionId(); + List orderRows = orderRowRepository.findByValidCodeNotInOrderByOrderTimeDescAndUnionId(param, Long.valueOf(unionId)); - /** - * 接收京粉指令指令 - * 高级菜单 - */ - public void sendOrderToWxByOrderJDAdvanced(String order, String fromWxid) { - int[] param = {-1}; - WXUtil.SuperAdmin superAdmin = super_admins.get(fromWxid); - String unionId = superAdmin.getUnionId(); - List orderRows = orderRowRepository.findByValidCodeNotInOrderByOrderTimeDescAndUnionId(param, Long.valueOf(unionId)); + List contents = new ArrayList<>(); + StringBuilder content = new StringBuilder(); + if (order.startsWith("高级")) { + content = new StringBuilder(); + order = order.replace("高级", ""); + if (order.startsWith("违规")) { + String days = order.replace("违规", ""); + Integer daysInt = 365; + if (Util.isNotEmpty(days)) { + daysInt = Integer.parseInt(days); + } + List filterOrdersByDays = filterOrdersByDate(orderRows, daysInt); - List contents = new ArrayList<>(); - StringBuilder content = new StringBuilder(); - if (order.startsWith("高级")) { - content = new StringBuilder(); - order = order.replace("高级", ""); - if (order.startsWith("违规")) { - String days = order.replace("违规", ""); - Integer daysInt = 365; - if (Util.isNotEmpty(days)) { - daysInt = Integer.parseInt(days); - } - List filterOrdersByDays = filterOrdersByDate(orderRows, daysInt); - - content.append("违规排行:"); - content.append(daysInt).append("天").append("\r\n"); + content.append("违规排行:"); + 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> 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()); - info.setOrderId(orderRow.getOrderId()); - info.setOrderDate(orderRow.getOrderTime()); - return info; - }).collect(Collectors.groupingBy(OrderInfo::getSkuName)); + 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()); + info.setOrderId(orderRow.getOrderId()); + info.setOrderDate(orderRow.getOrderTime()); + 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())).collect(Collectors.toList()); - Integer num = 0; - for (Map.Entry entry : sortedViolationCounts) { - num++; - String skuName = entry.getKey(); - Long count = entry.getValue(); + Integer num = 0; + for (Map.Entry entry : sortedViolationCounts) { + num++; + String skuName = entry.getKey(); + Long count = entry.getValue(); // 修改后直接使用已包含SKU信息的key - content.append("\n").append(num).append(",商品:").append(entry.getKey()) // 这里已包含SKU信息 - .append("\r\r").append(" 违规次数:").append(count).append("\r"); - List infos = orderInfoMap.get(skuName); - if (infos != null) { - for (OrderInfo info : infos) { - content.append("\n 订单:").append(info.getOrderId()).append("\r 下单:").append(info.getOrderDate()).append("\r"); - } + content.append("\n").append(num).append(",商品:").append(entry.getKey()) // 这里已包含SKU信息 + .append("\r\r").append(" 违规次数:").append(count).append("\r"); + List infos = orderInfoMap.get(skuName); + if (infos != null) { + for (OrderInfo info : infos) { + content.append("\n 订单:").append(info.getOrderId()).append("\r 下单:").append(info.getOrderDate()).append("\r"); } } - contents.add(content); } - // 订单查询 - if (order.startsWith("搜索")) { - order = order.replace("搜索", ""); + contents.add(content); + } + // 订单查询 + if (order.startsWith("搜索")) { + order = order.replace("搜索", ""); - content = new StringBuilder(); - // 精准查询订单号+精准查询sku+模糊查询收件人+模糊查询地址 - content.append("精准查询订单号:\r"); - List orderRowList = orderRowRepository.findByOrderId(Long.parseLong(order)); - if (!orderRowList.isEmpty()) { - OrderRow orderRow = orderRowList.get(0); - if (orderRow.getUnionId().equals(Long.parseLong(unionId))) { - content.append(orderUtil.getFormattedOrderInfo(orderRow, orderRow.getValidCode())); - } else { - content.append("订单不属于你,无法查询\r"); - } + content = new StringBuilder(); + // 精准查询订单号+精准查询sku+模糊查询收件人+模糊查询地址 + content.append("精准查询订单号:\r"); + List orderRowList = orderRowRepository.findByOrderId(Long.parseLong(order)); + if (!orderRowList.isEmpty()) { + OrderRow orderRow = orderRowList.get(0); + if (orderRow.getUnionId().equals(Long.parseLong(unionId))) { + content.append(orderUtil.getFormattedOrderInfo(orderRow, orderRow.getValidCode())); } else { - content.append("订单不存在\r"); + content.append("订单不属于你,无法查询\r"); } - contents.add(content); - - content = new StringBuilder(); - // 不统计已取消的订单 - content.append("精准查询sku,不统计已取消的订单:\r"); - int[] validCodes = {-1, 3}; - - List bySkuIdAndUnionId = orderRowRepository.findBySkuIdAndUnionId(validCodes, Long.parseLong(order), Long.parseLong(unionId)); - int size = bySkuIdAndUnionId.size(); - content.append("查询到").append(size).append("条订单\r"); - // 切割成20条20条返回前100条 - for (int i = 0; i < size; i += 20) { - List subList = bySkuIdAndUnionId.subList(i, Math.min(i + 20, size)); - content.append("第").append(i / 20 + 1).append("页:\r"); - for (OrderRow orderRow : subList) { - content.append(orderUtil.getFormattedOrderInfo(orderRow, orderRow.getValidCode())); - contents.add(content); - content = new StringBuilder(); - } - } - content = new StringBuilder(); - content.append("模糊查询收件人+模糊查询地址:\r"); - //List orderRowList = orderRowRepository - content.append("暂不支持"); - contents.add(content); - - + } else { + content.append("订单不存在\r"); } - if (order.startsWith("SKU")) { - content = new StringBuilder(); - order = order.replace("SKU", ""); - String[] split = order.split("\r\n"); - content.append("电脑端").append("\r\n"); - for (String s : split) { - content.append("https://item.jd.com/").append(s.trim()).append(".html").append("\r\n"); - } - wxUtil.sendTextMessage(fromWxid, content.toString(), 1, fromWxid); - content = new StringBuilder(); - content.append("手机端").append("\r\n"); - for (String s : split) { - content.append("https://item.m.jd.com/product/").append(s.trim()).append(".html").append("\r\n"); - } - wxUtil.sendTextMessage(fromWxid, content.toString(), 1, fromWxid); - content = new StringBuilder(); - contents.add(content); + contents.add(content); - } - // 转链 - if (order.startsWith("转链")) { - content = new StringBuilder(); - order = order.replace("转链", ""); - String[] split = order.split("\r\n"); - for (String s : split) { - content.append("https://item.jd.com/").append(s.trim()).append(".html").append("\r\n"); + content = new StringBuilder(); + // 不统计已取消的订单 + content.append("精准查询sku,不统计已取消的订单:\r"); + int[] validCodes = {-1, 3}; + + List bySkuIdAndUnionId = orderRowRepository.findBySkuIdAndUnionId(validCodes, Long.parseLong(order), Long.parseLong(unionId)); + int size = bySkuIdAndUnionId.size(); + content.append("查询到").append(size).append("条订单\r"); + // 切割成20条20条返回前100条 + for (int i = 0; i < size; i += 20) { + List subList = bySkuIdAndUnionId.subList(i, Math.min(i + 20, size)); + content.append("第").append(i / 20 + 1).append("页:\r"); + for (OrderRow orderRow : subList) { + content.append(orderUtil.getFormattedOrderInfo(orderRow, orderRow.getValidCode())); + contents.add(content); + content = new StringBuilder(); } - contents.add(content); - } - } else { - try { - sendOrderToWxByOrderJD("菜单", fromWxid); - } catch (Exception e) { - throw new RuntimeException(e); } + content = new StringBuilder(); + content.append("模糊查询收件人+模糊查询地址:\r"); + //List orderRowList = orderRowRepository + content.append("暂不支持"); + contents.add(content); + + } - if (!contents.isEmpty()) { - for (StringBuilder stringBuilder : contents) { - wxUtil.sendTextMessage(fromWxid, stringBuilder.toString(), 1, fromWxid); + if (order.startsWith("SKU")) { + content = new StringBuilder(); + order = order.replace("SKU", ""); + String[] split = order.split("\r\n"); + content.append("电脑端").append("\r\n"); + for (String s : split) { + content.append("https://item.jd.com/").append(s.trim()).append(".html").append("\r\n"); } + wxUtil.sendTextMessage(fromWxid, content.toString(), 1, fromWxid); + content = new StringBuilder(); + content.append("手机端").append("\r\n"); + for (String s : split) { + content.append("https://item.m.jd.com/product/").append(s.trim()).append(".html").append("\r\n"); + } + wxUtil.sendTextMessage(fromWxid, content.toString(), 1, fromWxid); + content = new StringBuilder(); + contents.add(content); + + } + // 转链 + if (order.startsWith("转链")) { + content = new StringBuilder(); + order = order.replace("转链", ""); + String[] split = order.split("\r\n"); + for (String s : split) { + content.append("https://item.jd.com/").append(s.trim()).append(".html").append("\r\n"); + } + contents.add(content); + } + } else { + try { + sendOrderToWxByOrderJD("菜单", fromWxid); + } catch (Exception e) { + throw new RuntimeException(e); } } - - /** - * 获取订单列表 - * - * @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) throws Exception { - JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_DG, LPF_SECRET_KEY_DG); - - UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest(); - PromotionCodeReq promotionCodeReq = new PromotionCodeReq(); - request.setPromotionCodeReq(promotionCodeReq); - request.setVersion("1.0"); - UnionOpenPromotionBysubunionidGetResponse response = client.execute(request); - - /** - * { - * "jd_union_open_promotion_bysubunionid_get_responce": { - * "getResult": { - * "code": "200", - * "data": { - * "clickURL": "https://union-click.jd.com/jdc?e=XXXXXX p=XXXXXXXXXXX", - * "weChatShortLink": "#小程序://京小街/****", - * "jShortCommand": "短口令", - * "shortURL": "https://u.jd.com/XXXXX", - * "jCommand": "6.0复制整段话 http://JhT7V5wlKygHDK京口令内容#J6UFE5iMn***" - * }, - * "message": "success" - * } - * } - * } - * */ - String result = ""; - if (Util.isNotEmpty(response)) { - if (response.getCode().equals("200")) { - result = response.getGetResult().getData().getShortURL(); - } - } else { - result = null; + if (!contents.isEmpty()) { + for (StringBuilder stringBuilder : contents) { + wxUtil.sendTextMessage(fromWxid, stringBuilder.toString(), 1, fromWxid); } - - 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; - //} +} + +/** + * 获取订单列表 + * + * @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) throws Exception { + JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_DG, LPF_SECRET_KEY_DG); + + UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest(); + PromotionCodeReq promotionCodeReq = new PromotionCodeReq(); + request.setPromotionCodeReq(promotionCodeReq); + request.setVersion("1.0"); + UnionOpenPromotionBysubunionidGetResponse response = client.execute(request); /** - * 消毒柜部分的业务逻辑 - */ - @Scheduled(fixedRate = 60000) // 每分钟执行一次 - public void cleanUpTimeoutStates() { - LocalDateTime now = LocalDateTime.now(); - 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); - logger.debug("Deleted timeout state for key: {}", key); - } - } catch (Exception e) { - logger.error("Error parsing interaction state: {}", e.getMessage()); - } - }); + * { + * "jd_union_open_promotion_bysubunionid_get_responce": { + * "getResult": { + * "code": "200", + * "data": { + * "clickURL": "https://union-click.jd.com/jdc?e=XXXXXX p=XXXXXXXXXXX", + * "weChatShortLink": "#小程序://京小街/****", + * "jShortCommand": "短口令", + * "shortURL": "https://u.jd.com/XXXXX", + * "jCommand": "6.0复制整段话 http://JhT7V5wlKygHDK京口令内容#J6UFE5iMn***" + * }, + * "message": "success" + * } + * } + * } + * */ + String result = ""; + if (Util.isNotEmpty(response)) { + if (response.getCode().equals("200")) { + result = response.getGetResult().getData().getShortURL(); + } + } else { + result = null; } - public void handleUserInteraction(String fromWxid, String message) { - String key = INTERACTION_STATE_PREFIX + fromWxid; + return result; +} + +/** + * 消毒柜部分的业务逻辑 + */ +@Scheduled(fixedRate = 60000) // 每分钟执行一次 +public void cleanUpTimeoutStates() { + LocalDateTime now = LocalDateTime.now(); + redisTemplate.keys(INTERACTION_STATE_PREFIX + "*").forEach(key -> { String stateJson = redisTemplate.opsForValue().get(key); - UserInteractionState state; - if (stateJson == null) { - state = new UserInteractionState(); - logger.debug("New interaction state created for user: {}", fromWxid); - } 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); - logger.debug("Deleted timeout state for user: {}", fromWxid); - state = new UserInteractionState(); - } - } catch (Exception e) { - logger.error("Error parsing interaction state: {}", e.getMessage()); + 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); + logger.debug("Deleted timeout state for key: {}", key); + } + } catch (Exception e) { + logger.error("Error parsing interaction state: {}", e.getMessage()); + } + }); +} +//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; +//} + +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(); + logger.debug("New interaction state created for user: {}", fromWxid); + } 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); + logger.debug("Deleted timeout state for user: {}", fromWxid); state = new UserInteractionState(); } - } - state.updateLastInteractionTime(); - - switch (state.getCurrentState()) { - case INIT: - if ("礼金".equals(message)) { - state.setCurrentState(GIFT_MONEY_FLOW); - state.setCurrentStep(STEP_PRODUCT_LINK); - wxUtil.sendTextMessage(fromWxid, "请输入商品链接:", 1, fromWxid); - logger.info("进入礼金开通流程 - 商品链接步骤"); - } - if ("登记".equals(message)) { - // 开始登记新的订单 - state.setCurrentState(DISINFECTANT_CABINET); - state.setCurrentField("orderId"); - wxUtil.sendTextMessage(fromWxid, "请输入订单号:", 1, fromWxid); - logger.debug("User {} entered DISINFECTANT_CABINET state", fromWxid); - } - break; - case GIFT_MONEY_FLOW: - handleGiftMoneyFlow(fromWxid, message, state); - break; - case PRODUCT_ORDER_REGISTRATION: - handleProductOrderRegistration(fromWxid, message, state); - break; - default: - wxUtil.sendTextMessage(fromWxid, "无效的状态,请重新开始对话", 1, fromWxid); - state.setCurrentState(INIT); - logger.debug("User {} reset to INIT state due to invalid state", fromWxid); - break; - } - - try { - redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(state), TIMEOUT_MINUTES, TimeUnit.MINUTES); - logger.debug("Saved interaction state for user {}: {}", fromWxid, state); } catch (Exception e) { - logger.error("Error saving interaction state: {}", e.getMessage()); + logger.error("Error parsing interaction state: {}", e.getMessage()); + state = new UserInteractionState(); } } + state.updateLastInteractionTime(); - - - // 新增礼金流程处理方法 - private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) { - if ("礼金".equals(message)) { - state.reset(); // 重置流程 - wxUtil.sendTextMessage(fromWxid, "流程已重置,请重新开始", 1, fromWxid); - return; - } - - try { - switch (state.getCurrentStep()) { - case STEP_PRODUCT_LINK: - // 解析商品链接获取SKU - 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.setCurrentStep(STEP_AMOUNT); - wxUtil.sendTextMessage(fromWxid, "商品信息:\n" + productInfo.get("name") + "\n当前价格:" + productInfo.get("price") + "\n请输入开通金额(元):", 1, fromWxid); - break; - - case STEP_AMOUNT: - if (!isValidAmount(message)) { - wxUtil.sendTextMessage(fromWxid, "金额格式错误,请重新输入", 1, fromWxid); - return; - } - state.getCollectedFields().put("amount", message); - state.setCurrentStep(STEP_QUANTITY); - wxUtil.sendTextMessage(fromWxid, "请输入开通数量:", 1, fromWxid); - break; - - case STEP_QUANTITY: - if (!isValidQuantity(message)) { - wxUtil.sendTextMessage(fromWxid, "数量格式错误,请重新输入", 1, fromWxid); - return; - } - state.getCollectedFields().put("quantity", 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); - state.reset(); // 完成流程 - break; + switch (state.getCurrentState()) { + case INIT: + if ("礼金".equals(message)) { + state.setCurrentState(GIFT_MONEY_FLOW); + state.setCurrentStep(STEP_PRODUCT_LINK); + wxUtil.sendTextMessage(fromWxid, "请输入商品链接:", 1, fromWxid); + logger.info("进入礼金开通流程 - 商品链接步骤"); } - } catch (Exception e) { - logger.error("礼金流程处理异常", e); - wxUtil.sendTextMessage(fromWxid, "系统异常,流程已终止", 1, fromWxid); - state.reset(); + if ("登记".equals(message)) { + // 开始登记新的订单 + state.setCurrentState(DISINFECTANT_CABINET); + state.setCurrentField("orderId"); + wxUtil.sendTextMessage(fromWxid, "请输入订单号:", 1, fromWxid); + logger.debug("User {} entered DISINFECTANT_CABINET state", fromWxid); + } + break; + case GIFT_MONEY_FLOW: + handleGiftMoneyFlow(fromWxid, message, state); + break; + case PRODUCT_ORDER_REGISTRATION: + handleProductOrderRegistration(fromWxid, message, state); + break; + default: + wxUtil.sendTextMessage(fromWxid, "无效的状态,请重新开始对话", 1, fromWxid); + state.setCurrentState(INIT); + logger.debug("User {} reset to INIT state due to invalid state", fromWxid); + break; + } + + try { + redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(state), TIMEOUT_MINUTES, TimeUnit.MINUTES); + logger.debug("Saved interaction state for user {}: {}", fromWxid, state); + } catch (Exception e) { + logger.error("Error saving interaction state: {}", e.getMessage()); + } +} + +// 新增礼金流程处理方法 +private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) { + if ("礼金".equals(message)) { + state.reset(); // 重置流程 + wxUtil.sendTextMessage(fromWxid, "流程已重置,请重新开始", 1, fromWxid); + return; + } + + try { + switch (state.getCurrentStep()) { + case STEP_PRODUCT_LINK: + // 解析商品链接获取SKU + 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.setCurrentStep(STEP_AMOUNT); + wxUtil.sendTextMessage(fromWxid, "商品信息:\n" + productInfo.get("name") + "\n当前价格:" + productInfo.get("price") + "\n请输入开通金额(元):", 1, fromWxid); + break; + + case STEP_AMOUNT: + if (!isValidAmount(message)) { + wxUtil.sendTextMessage(fromWxid, "金额格式错误,请重新输入", 1, fromWxid); + return; + } + state.getCollectedFields().put("amount", message); + state.setCurrentStep(STEP_QUANTITY); + wxUtil.sendTextMessage(fromWxid, "请输入开通数量:", 1, fromWxid); + break; + + case STEP_QUANTITY: + if (!isValidQuantity(message)) { + wxUtil.sendTextMessage(fromWxid, "数量格式错误,请重新输入", 1, fromWxid); + return; + } + state.getCollectedFields().put("quantity", 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); + state.reset(); // 完成流程 + break; } + } catch (Exception e) { + logger.error("礼金流程处理异常", e); + wxUtil.sendTextMessage(fromWxid, "系统异常,流程已终止", 1, fromWxid); + state.reset(); } - private String parseSkuFromUrl(String url) { - // 实现从URL中解析SKU的逻辑 - return "123456"; // 示例返回值 - } +} - private boolean isValidAmount(String input) { - return input.matches("^\\d+(\\.\\d{1,2})?$"); - } +private String parseSkuFromUrl(String url) { + // 实现从URL中解析SKU的逻辑 + return "123456"; // 示例返回值 +} - private Map queryProductInfo(String skuId) { - // 调用京东商品查询API(需要实现) - return Map.of("name", "示例商品", "price", "299.00"); - } +private boolean isValidAmount(String input) { + return input.matches("^\\d+(\\.\\d{1,2})?$"); +} - private boolean isValidQuantity(String input) { - return input.matches("^\\d+$"); - } +private Map queryProductInfo(String skuId) { + // 调用京东商品查询API(需要实现) + return Map.of("name", "示例商品", "price", "299.00"); +} - private boolean activateGiftMoney(String skuId, double amount, int quantity) { - // 实现实际的开通接口调用 +private boolean isValidQuantity(String input) { + return input.matches("^\\d+$"); +} + +private boolean activateGiftMoney(String skuId, double amount, int quantity) { + // 实现实际的开通接口调用 + return true; +} + +private void handleProductOrderRegistration(String fromWxid, String message, UserInteractionState state) { + switch (state.getCurrentProductOrderStep()) { + case STEP_ORDER_ID: + if (!message.matches("^\\d{10,20}$")) { + wxUtil.sendTextMessage(fromWxid, "⚠️ 订单号格式错误(需10-20位数字)", 1, fromWxid); + return; + } + state.getCollectedFields().put("orderId", message); + state.setCurrentProductOrderStep(STEP_PRODUCT_INFO); + wxUtil.sendTextMessage(fromWxid, "请输入商品信息(格式:商品名称-类型编号)\n类型对照:1-家电 2-数码 3-服饰\n示例:格力空调-1", 1, fromWxid); + break; + + case STEP_PRODUCT_INFO: + String[] productInfo = message.split("-"); + if (productInfo.length != 2 || !productInfo[1].matches("[1-3]")) { + wxUtil.sendTextMessage(fromWxid, "❌ 格式错误或类型编号无效", 1, fromWxid); + return; + } + state.getCollectedFields().put("skuName", productInfo[0]); + state.getCollectedFields().put("skuType", productInfo[1]); + + state.setCurrentProductOrderStep(UserInteractionState.ProductOrderStep.STEP_RECIPIENT_INFO); + wxUtil.sendTextMessage(fromWxid, "请输入收件信息(格式:姓名-电话-地址)\n示例:张三-13812345678-北京市朝阳区", 1, fromWxid); + break; + + case STEP_RECIPIENT_INFO: + String[] recipientInfo = message.split("-"); + if (recipientInfo.length < 3) { + wxUtil.sendTextMessage(fromWxid, "❌ 格式错误,请按示例格式输入", 1, fromWxid); + return; + } + state.getCollectedFields().put("recipientName", recipientInfo[0]); + state.getCollectedFields().put("recipientPhone", recipientInfo[1]); + state.getCollectedFields().put("recipientAddress", String.join("-", Arrays.copyOfRange(recipientInfo, 2, recipientInfo.length))); + + // 生成确认信息 + String confirmMsg = buildConfirmMessage(state); + wxUtil.sendTextMessage(fromWxid, confirmMsg, 1, fromWxid); + state.setCurrentProductOrderStep(STEP_REVIEW_CONFIRM); + break; + + case STEP_REVIEW_CONFIRM: + if ("确认".equals(message)) { + boolean success = saveFullProductOrder(state, fromWxid); + wxUtil.sendTextMessage(fromWxid, success ? "✅ 订单登记成功!" : "❌ 保存失败,请联系管理员", 1, fromWxid); + state.reset(); + } else { + state.setCurrentProductOrderStep(STEP_ORDER_ID); + wxUtil.sendTextMessage(fromWxid, "请重新输入订单号:", 1, fromWxid); + } + break; + } +} + +private String buildConfirmMessage(UserInteractionState state) { + return "📋 请确认登记信息:\n" + "────────────────\n" + "▪ 订单号:" + state.getCollectedFields().get("orderId") + "\n" + "▪ 商品名称:" + state.getCollectedFields().get("skuName") + "\n" + "▪ 商品类型:" + getTypeDesc(state.getCollectedFields().get("skuType")) + "\n" + "▪ 收件人:" + state.getCollectedFields().get("recipientName") + "\n" + "▪ 联系方式:" + state.getCollectedFields().get("recipientPhone") + "\n" + "▪ 收货地址:" + state.getCollectedFields().get("recipientAddress") + "\n" + "────────────────\n" + "回复【确认】提交,其他内容重新开始"; +} + +private boolean saveFullProductOrder(UserInteractionState state, String fromWxid) { + try { + ProductOrder order = new ProductOrder(); + order.setOrderId(state.getCollectedFields().get("orderId")); + order.setSkuName(state.getCollectedFields().get("skuName")); + order.setSkuType(Integer.valueOf(state.getCollectedFields().get("skuType"))); + order.setRecipientName(state.getCollectedFields().get("recipientName")); + order.setRecipientPhone(state.getCollectedFields().get("recipientPhone")); + order.setRecipientAddress(state.getCollectedFields().get("recipientAddress")); + order.setOrderTime(new Date()); // 设置下单时间为当前时间 + order.setWhoOrder(state.getCollectedFields().get("recipientName")); // 关联管理员信息 + order.setIsReviewed(false); // 默认是否晒图登记 + order.setIsCashbackReceived(false); // 默认是否返现到账 + order.setFromWxid(fromWxid); // 设置当前交互的wxid + + productOrderRepository.save(order); + logger.info("订单登记成功:{}", order); return true; + } catch (Exception e) { + logger.error("订单保存异常:{}", e.getMessage()); + return false; } - private void handleProductOrderRegistration(String fromWxid, String message, UserInteractionState state) { - switch (state.getCurrentProductOrderStep()) { - case STEP_ORDER_ID: - if (!message.matches("^\\d{10,20}$")) { - wxUtil.sendTextMessage(fromWxid, "⚠️ 订单号格式错误(需10-20位数字)", 1, fromWxid); - return; - } - state.getCollectedFields().put("orderId", message); - state.setCurrentProductOrderStep(STEP_PRODUCT_INFO); - wxUtil.sendTextMessage(fromWxid, - "请输入商品信息(格式:商品名称-类型编号)\n类型对照:1-家电 2-数码 3-服饰\n示例:格力空调-1", 1, fromWxid); - break; - - case STEP_PRODUCT_INFO: - String[] productInfo = message.split("-"); - if (productInfo.length != 2 || !productInfo[1].matches("[1-3]")) { - wxUtil.sendTextMessage(fromWxid, "❌ 格式错误或类型编号无效", 1, fromWxid); - return; - } - state.getCollectedFields().put("skuName", productInfo[0]); - state.getCollectedFields().put("skuType", productInfo[1]); - - state.setCurrentProductOrderStep(UserInteractionState.ProductOrderStep.STEP_RECIPIENT_INFO); - wxUtil.sendTextMessage(fromWxid, - "请输入收件信息(格式:姓名-电话-地址)\n示例:张三-13812345678-北京市朝阳区", 1, fromWxid); - break; - - case STEP_RECIPIENT_INFO: - String[] recipientInfo = message.split("-"); - if (recipientInfo.length < 3) { - wxUtil.sendTextMessage(fromWxid, "❌ 格式错误,请按示例格式输入", 1, fromWxid); - return; - } - state.getCollectedFields().put("recipientName", recipientInfo[0]); - state.getCollectedFields().put("recipientPhone", recipientInfo[1]); - state.getCollectedFields().put("recipientAddress", String.join("-", Arrays.copyOfRange(recipientInfo, 2, recipientInfo.length))); - - // 生成确认信息 - String confirmMsg = buildConfirmMessage(state); - wxUtil.sendTextMessage(fromWxid, confirmMsg, 1, fromWxid); - state.setCurrentProductOrderStep(STEP_REVIEW_CONFIRM); - break; - - case STEP_REVIEW_CONFIRM: - if ("确认".equals(message)) { - boolean success = saveFullProductOrder(state, fromWxid); - wxUtil.sendTextMessage(fromWxid, - success ? "✅ 订单登记成功!" : "❌ 保存失败,请联系管理员", 1, fromWxid); - state.reset(); - } else { - state.setCurrentProductOrderStep(STEP_ORDER_ID); - wxUtil.sendTextMessage(fromWxid, "请重新输入订单号:", 1, fromWxid); - } - break; - } - } - - - private String buildConfirmMessage(UserInteractionState state) { - return "📋 请确认登记信息:\n" + - "────────────────\n" + - "▪ 订单号:" + state.getCollectedFields().get("orderId") + "\n" + - "▪ 商品名称:" + state.getCollectedFields().get("skuName") + "\n" + - "▪ 商品类型:" + getTypeDesc(state.getCollectedFields().get("skuType")) + "\n" + - "▪ 收件人:" + state.getCollectedFields().get("recipientName") + "\n" + - "▪ 联系方式:" + state.getCollectedFields().get("recipientPhone") + "\n" + - "▪ 收货地址:" + state.getCollectedFields().get("recipientAddress") + "\n" + - "────────────────\n" + - "回复【确认】提交,其他内容重新开始"; - } - - private boolean saveFullProductOrder(UserInteractionState state, String fromWxid) { - try { - ProductOrder order = new ProductOrder(); - order.setOrderId(state.getCollectedFields().get("orderId")); - order.setSkuName(state.getCollectedFields().get("skuName")); - order.setSkuType(Integer.valueOf(state.getCollectedFields().get("skuType"))); - order.setRecipientName(state.getCollectedFields().get("recipientName")); - order.setRecipientPhone(state.getCollectedFields().get("recipientPhone")); - order.setRecipientAddress(state.getCollectedFields().get("recipientAddress")); - order.setOrderTime(new Date()); // 设置下单时间为当前时间 - order.setWhoOrder(state.getCollectedFields().get("recipientName")); // 关联管理员信息 - order.setIsReviewed(false); // 默认是否晒图登记 - order.setIsCashbackReceived(false); // 默认是否返现到账 - order.setFromWxid(fromWxid); // 设置当前交互的wxid - - productOrderRepository.save(order); - logger.info("订单登记成功:{}", order); - return true; - } catch (Exception e) { - logger.error("订单保存异常:{}", e.getMessage()); - return false; - } - } - - private String getTypeDesc(String skuType) { - return switch (skuType) { - case "1" -> "家电"; - case "2" -> "数码"; - case "3" -> "服饰"; - default -> "未知类型"; - }; - } - - +} +private String getTypeDesc(String skuType) { + return switch (skuType) { + case "1" -> "家电"; + case "2" -> "数码"; + case "3" -> "服饰"; + default -> "未知类型"; + }; +} // 定义一个内部类来存储用户交互状态 @Getter @@ -1380,45 +1252,62 @@ public class JDUtil { private String currentField; // 当前正在询问的字段 private ProductOrderStep currentProductOrderStep; - public UserInteractionState() { - this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); - this.currentState = INIT; - this.collectedFields = new HashMap<>(); - this.currentField = null; - - } - - public void updateLastInteractionTime() { - this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); - } - - // UserInteractionState类缺少reset方法 - public void reset() { - this.currentState = INIT; - this.collectedFields.clear(); - this.currentStep = null; - updateLastInteractionTime(); - } - + public UserInteractionState() { + this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); + this.currentState = INIT; + this.collectedFields = new HashMap<>(); + this.currentField = null; } - // 限流异常类(需自定义) - public static class RateLimitExceededException extends RuntimeException { - public RateLimitExceededException(String message) { - super(message); - } + public void updateLastInteractionTime() { + this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); } - @Setter - @Getter - public static class OrderInfo { - private String skuName; - private Long count; - private Long orderId; - private Date orderDate; - + // UserInteractionState类缺少reset方法 + public void reset() { + this.currentState = INIT; + this.collectedFields.clear(); + this.currentStep = null; + updateLastInteractionTime(); } } + +// 限流异常类(需自定义) +public static class RateLimitExceededException extends RuntimeException { + public RateLimitExceededException(String message) { + super(message); + } +} + +@Setter +@Getter +public static class OrderInfo { + private String skuName; + private Long count; + private Long orderId; + private Date orderDate; + +} + + + // 统计指标DTO + @Getter + @AllArgsConstructor + class OrderStats { + private long totalOrders; // 总订单数 + private long validOrders; // 有效订单数(不含取消) + private long paidOrders; // 已付款订单 + private double paidCommission; // 已付款佣金 + private long pendingOrders; // 待付款订单 + private double pendingCommission; // 待付款佣金 + private long canceledOrders; // 已取消订单 + private long completedOrders; // 已完成订单 + private double completedCommission;// 已完成佣金 + private long violations; // 违规订单数 + private double violationCommission;// 违规佣金 + } + +}