订单附带京粉每日统计

This commit is contained in:
Van0313
2025-04-17 14:36:46 +08:00
parent 609451a9d6
commit 1f91a349da
6 changed files with 120 additions and 7 deletions

View File

@@ -116,7 +116,7 @@ public class JDUtil {
this.orderUtil = orderUtil;
}
private static List<OrderRow> filterOrdersByDate(List<OrderRow> orderRows, int daysBack) {
private List<OrderRow> filterOrdersByDate(List<OrderRow> 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<OrderRow> getStreamForWeiGui(List<OrderRow> todayOrders) {
private Stream<OrderRow> getStreamForWeiGui(List<OrderRow> todayOrders) {
return todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 13 || orderRow.getValidCode() == 25 || orderRow.getValidCode() == 26 || orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 29);
}

View File

@@ -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<WXUtil.SuperAdmin> superAdmins = getSuperAdmins(wxId);
List<Long> unionIds = new ArrayList<>();
for (WXUtil.SuperAdmin superAdmin : superAdmins) {
String unionId = superAdmin.getUnionId();
unionIds.add(Long.valueOf(unionId));
}
List<OrderRow> orderRows = orderRowRepository.findByValidCodeNotInAndUnionIdIn(param, unionIds);
List<OrderRow> todayOrders = filterOrdersByDate(orderRows, 0);
// 分割统计每个京粉今天下单多少个订单,避免一天一个京粉下单太多
HashMap<String, List<OrderRow>> stringListHashMap = new HashMap<>();
List<OrderRow> 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<OrderRow> filterOrdersByDate(List<OrderRow> 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<OrderRow> 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<OrderRow> getStreamForWeiGui(List<OrderRow> 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;// 违规佣金
}
}

View File

@@ -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());
// 方案

View File

@@ -1,6 +1,8 @@
server:
port: 6666
spring:
main:
allow-circular-references: true
application:
name: jd
#数据源配置

View File

@@ -1,6 +1,8 @@
server:
port: 6666
spring:
main:
allow-circular-references: true
application:
name: jd
#数据源配置

View File

@@ -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: