From 1f91a349daf3f4bb19c248272e35ce7fa0f28624 Mon Sep 17 00:00:00 2001 From: Van0313 <60689272+Van0313@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:36:46 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E9=99=84=E5=B8=A6=E4=BA=AC?= =?UTF-8?q?=E7=B2=89=E6=AF=8F=E6=97=A5=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/van/business/util/JDUtil.java | 4 +- .../java/cn/van/business/util/OrderUtil.java | 109 +++++++++++++++++- .../java/cn/van/business/util/WXUtil.java | 5 + src/main/resources/application-dev.yml | 2 + src/main/resources/application-prod.yml | 2 + src/main/resources/application.yml | 5 +- 6 files changed, 120 insertions(+), 7 deletions(-) diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index a00e501..bb10ff5 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -116,7 +116,7 @@ public class JDUtil { this.orderUtil = orderUtil; } - private static List filterOrdersByDate(List orderRows, int daysBack) { + private List filterOrdersByDate(List orderRows, int daysBack) { LocalDate now = LocalDate.now(); return orderRows.stream().filter(order -> { @@ -128,7 +128,7 @@ public class JDUtil { }).collect(Collectors.toList()); } - private static Stream getStreamForWeiGui(List todayOrders) { + private Stream getStreamForWeiGui(List todayOrders) { return todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 13 || orderRow.getValidCode() == 25 || orderRow.getValidCode() == 26 || orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 29); } diff --git a/src/main/java/cn/van/business/util/OrderUtil.java b/src/main/java/cn/van/business/util/OrderUtil.java index 3be1d23..b11fa78 100644 --- a/src/main/java/cn/van/business/util/OrderUtil.java +++ b/src/main/java/cn/van/business/util/OrderUtil.java @@ -3,6 +3,8 @@ package cn.van.business.util; import cn.van.business.enums.ValidCodeConverter; import cn.van.business.model.jd.OrderRow; import cn.van.business.repository.OrderRowRepository; +import lombok.AllArgsConstructor; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -11,10 +13,16 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import static cn.van.business.util.WXUtil.getRemarkFromJdid; -import static cn.van.business.util.WXUtil.getWxidFromJdid; +import static cn.van.business.util.WXUtil.*; /** @@ -32,9 +40,9 @@ public class OrderUtil { private OrderRowRepository orderRowRepository; @Autowired private WXUtil wxUtil; + //标记唯一订单行:订单+sku维度的唯一标识 private static final String ORDER_ROW_KEY = "jd:order:row:"; - private static final Logger logger = LoggerFactory.getLogger(OrderUtil.class); /** * 手动调用 将订单发送到微信 @@ -55,6 +63,38 @@ public class OrderUtil { String wxId = getWxidFromJdid(orderRow.getUnionId().toString()); if (Util.isNotEmpty(wxId)) { wxUtil.sendTextMessage(wxId, content, 1, wxId, true); + // 加一个简短的今日订单统计 + int[] param = {-1}; + List superAdmins = getSuperAdmins(wxId); + List unionIds = new ArrayList<>(); + for (WXUtil.SuperAdmin superAdmin : superAdmins) { + String unionId = superAdmin.getUnionId(); + unionIds.add(Long.valueOf(unionId)); + } + List orderRows = orderRowRepository.findByValidCodeNotInAndUnionIdIn(param, unionIds); + + List todayOrders = filterOrdersByDate(orderRows, 0); + // 分割统计每个京粉今天下单多少个订单,避免一天一个京粉下单太多 + HashMap> stringListHashMap = new HashMap<>(); + List cachedOrders = new ArrayList<>(); + for (OrderRow todayOrder : todayOrders) { + String unionId = todayOrder.getUnionId().toString(); + if (stringListHashMap.containsKey(unionId)) { + cachedOrders = stringListHashMap.get(unionId); + } else { + cachedOrders = new ArrayList<>(); + } + cachedOrders.add(todayOrder); + stringListHashMap.put(unionId, cachedOrders); + + } + // 只统计今天下单的京粉,因为有的京粉休息是不下单的 + stringListHashMap.forEach((unionId, orderRows2) -> { + OrderStats stats = calculateStats(orderRows2); + StringBuilder stringBuilder = buildStatsContent("京粉 :" + getRemarkFromJdid(unionId) + "今日统计", stats); + wxUtil.sendTextMessage(wxId, stringBuilder.toString(), 1, wxId, true); + }); + } } @@ -191,4 +231,67 @@ public class OrderUtil { + "下单:" + formatter.format(orderRow.getOrderTime()) + "\r" + "完成:" + (orderRow.getFinishTime() != null ? formatter.format(orderRow.getFinishTime()) : "未完成") + "\r"; } + + /** + * JDUtil拷贝的方法,避免循环注入 + * */ + + private List filterOrdersByDate(List orderRows, int daysBack) { + LocalDate now = LocalDate.now(); + + return orderRows.stream().filter(order -> { + // 将 Date 转换为 LocalDate + LocalDate orderDate = order.getOrderTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + + // 计算是否在给定的天数内 + return !orderDate.isBefore(now.minusDays(daysBack)) && !orderDate.isAfter(now); + }).collect(Collectors.toList()); + } + 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//[爱心][Wow][Packet][Party][Broken][心碎][亲亲][色] + .append("* ").append(title).append(" *\n").append("━━━━━━━━━━━━\n").append("[爱心] 订单总数:").append(stats.getTotalOrders()).append("\n") // [文件] + .append("[Party] 有效订单:").append(stats.getValidOrders()).append("\n") // [OK] + .append("[心碎]已取消:").append(stats.getCanceledOrders()).append("\n") // [禁止] + + .append("────────────\n").append("[爱心]已付款:").append(stats.getPaidOrders()).append("\n") // [钱袋] + .append("[Packet] 已付款佣金:").append(String.format("%.2f", stats.getPaidCommission())).append("\n") // [钞票] + .append("────────────\n").append("[Wow] 待付款:").append(stats.getPendingOrders()).append("\n") // [时钟] + .append("[Packet] 待付款佣金:").append(String.format("%.2f", stats.getPendingCommission())).append("\n") // [钱] + //.append("────────────\n").append("[亲亲] 已完成:").append(stats.getCompletedOrders()).append("\n") // [旗帜] + //.append("[Packet] 已完成佣金:").append(String.format("%.2f", stats.getCompletedCommission())).append("\n") // [信用卡] + //.append("────────────\n").append("[Emm] 违规订单:").append(stats.getViolations()).append("\n") // [警告] + //.append("[Broken] 违规佣金:").append(String.format("%.2f", stats.getViolationCommission())).append("\n") // [炸弹] + .append("━━━━━━━━━━━━"); + return content; + } + private Stream getStreamForWeiGui(List todayOrders) { + return todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 13 || orderRow.getValidCode() == 25 || orderRow.getValidCode() == 26 || orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 29); + } + + // 统计指标DTO + @Getter + @AllArgsConstructor + static + 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;// 违规佣金 + } } diff --git a/src/main/java/cn/van/business/util/WXUtil.java b/src/main/java/cn/van/business/util/WXUtil.java index d68ab4b..ada7bfc 100644 --- a/src/main/java/cn/van/business/util/WXUtil.java +++ b/src/main/java/cn/van/business/util/WXUtil.java @@ -156,6 +156,11 @@ public class WXUtil { jdidToWxidMap.put(admin7.getUnionId(), admin7.getWxid()); jdidToRemarkMap.put(admin7.getUnionId(), admin7.getName()); + SuperAdmin admin8 = new SuperAdmin("wxid_ytpc72mdoskt22", "梓豪", "1003068753", "e335738c819a7c3343d4dde52c393880", "b56abdd9b177466ba2afb6f0ee89709c"); + super_admins.put(admin8.getWxid() + admin8.getUnionId(), admin8); + jdidToWxidMap.put(admin8.getUnionId(), admin8.getWxid()); + jdidToRemarkMap.put(admin8.getUnionId(), admin8.getName()); + // 方案 diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index b1c6b50..3018c30 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,6 +1,8 @@ server: port: 6666 spring: + main: + allow-circular-references: true application: name: jd #数据源配置 diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index b1c6b50..3018c30 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -1,6 +1,8 @@ server: port: 6666 spring: + main: + allow-circular-references: true application: name: jd #数据源配置 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3f8a6a2..ca51e13 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,8 @@ server: port: 8080 spring: + main: + allow-circular-references: true application: name: jd profiles: @@ -26,8 +28,7 @@ spring: execution: pool: core-size: 32 - main: - allow-circular-references: true + # token配置 token: