@@ -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 ; // 违规佣金
}
}