Răsfoiți Sursa

统计新增优惠金额和设备使用率

skyline 2 ani în urmă
părinte
comite
29107b687f

+ 43 - 2
admin/src/main/java/com/kym/admin/jobs/StationStatJob.java

@@ -2,6 +2,7 @@ package com.kym.admin.jobs;
 
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.kym.common.utils.CommUtil;
 import com.kym.entity.admin.ConnectorInfo;
 import com.kym.entity.admin.StationStatDay;
 import com.kym.entity.admin.StationStatMonth;
@@ -10,6 +11,7 @@ import com.kym.service.admin.ConnectorInfoService;
 import com.kym.service.admin.StationStatDayService;
 import com.kym.service.admin.StationStatMonthService;
 import com.kym.service.miniapp.ChargeOrderService;
+import jakarta.annotation.PostConstruct;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
@@ -17,12 +19,15 @@ import org.springframework.stereotype.Component;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
  * 站点统计定时任务
+ *
+ * @author skyline
  */
 @Component
 @Slf4j
@@ -46,9 +51,10 @@ public class StationStatJob {
     // 每天14:30执行一次,通过charge_app.t_charge_order表统计start_time为前一天且充电金额大于100的充电订单,分别统计充电人数、订单数、充电总费用、充电总电量、平均充电电量、平均充电费用、平均订单费用、平均订单电量
 
     /**
-     * 日统计,每月第一天下午14:30启动,统计上日数据
+     * 日统计,每下午14:30启动,统计上日数据
      */
     @Scheduled(cron = "0 30 14 * * ?")
+    // 定时每日下午14:30
     private void dayStat() {
         log.info("执行站点日统计定时任务-开始");
         var statDay = LocalDateTime.now().minusDays(1);
@@ -74,6 +80,30 @@ public class StationStatJob {
         log.info("执行站点月统计定时任务-结束");
     }
 
+    // 只执行一次
+//    @PostConstruct
+    private void init() {
+        log.info("执行站点初始化定时任务-开始");
+        // 2023-08-01 00:00:00
+//        var statMonth = LocalDateTime.of(2023, 12, 1, 0, 0);
+//        var endMonth = LocalDateTime.of(2023, 12, 1, 0, 0);
+//        var startTime = statMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+//        var endTime = endMonth.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+//        var chargeOrderList = getChargeOrders(startTime, endTime);
+//        monthService.saveBatch((Collection<StationStatMonth>) getStationStat(chargeOrderList, false));
+//
+//        // 将订单按照日为单位分组
+//        var chargeOrderMap = chargeOrderList.stream().collect(Collectors.groupingBy(order ->
+//                order.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+//        ));
+//        // chargeOrderMap按照key升序排序
+//        var chargeOrderMapSort = chargeOrderMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(
+//                Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
+//
+//        chargeOrderMapSort.forEach((k, v) -> dayService.saveBatch(((Collection<StationStatDay>) getStationStat(v, true))));
+
+        log.info("执行站点初始化定时任务-结束");
+    }
 
     private List<ChargeOrder> getChargeOrders(LocalDateTime startTime, LocalDateTime endTime) {
         // 通过charge_app.t_charge_order表统计start_time为前一天且充电金额大于100的有效充电订单
@@ -87,7 +117,6 @@ public class StationStatJob {
         return res;
     }
 
-
     private Collection<?> getStationStat(List<ChargeOrder> chargeOrderList, boolean isDayStat) {
         // 统计每个站点的connector_id数量
         var stationConnectorCountMap = connectorInfoService.list().stream().collect(Collectors.groupingBy(ConnectorInfo::getStationId, Collectors.counting()));
@@ -103,9 +132,14 @@ public class StationStatJob {
                     var totalMoney = chargeOrders.stream().mapToInt(ChargeOrder::getTotalMoney).sum();
                     var elecMoney = chargeOrders.stream().mapToInt(ChargeOrder::getElecMoney).sum();
                     var serviceMoney = chargeOrders.stream().mapToInt(ChargeOrder::getServiceMoney).sum();
+                    var serviceMoneyDiscount = chargeOrders.stream().mapToInt(ChargeOrder::getServiceMoneyDiscount).sum();
+                    var discountAmount = chargeOrders.stream().mapToInt(ChargeOrder::getDiscountAmount).sum();
                     var totalPower = chargeOrders.stream().mapToDouble(ChargeOrder::getTotalPower).sum();
                     var avgPower = chargeOrders.stream().mapToDouble(ChargeOrder::getTotalPower).average().orElse(0.0);
                     var avgOrderMoney = chargeOrders.stream().mapToInt(ChargeOrder::getTotalMoney).average().orElse(0);
+                    // 充电桩使用率 = 有订单的充电桩数量 / 总充电桩数
+                    var connectorUsageRate = (double) chargeOrders.stream().filter(CommUtil.distinctByKey(ChargeOrder::getConnectorId)).count() / stationConnectorCountMap.get(entry.getKey());
+                    ;
                     return isDayStat
                             ? new StationStatDay()
                             .setStationId(entry.getKey())
@@ -115,10 +149,15 @@ public class StationStatJob {
                             .setTotalMoney(totalMoney)
                             .setElecMoney(elecMoney)
                             .setServiceMoney(serviceMoney)
+                            .setServiceMoneyDiscount(serviceMoneyDiscount)
+                            .setDiscountAmount(discountAmount)
+
                             .setTotalPower(totalPower)
                             .setAvgOrderElec(avgPower)
                             .setAvgOrderMoney((int) avgOrderMoney)
                             .setAvgConnectorElec(totalPower / (stationConnectorCountMap.get(entry.getKey())))
+                            .setConnectorUsageRate(connectorUsageRate)
+
                             : new StationStatMonth()
                             .setStationId(entry.getKey())
                             .setStatMonth(DateUtil.format(LocalDateTime.now().minusMonths(1), "yyyy-MM"))
@@ -127,6 +166,8 @@ public class StationStatJob {
                             .setTotalMoney(totalMoney)
                             .setElecMoney(elecMoney)
                             .setServiceMoney(serviceMoney)
+                            .setServiceMoneyDiscount(serviceMoneyDiscount)
+                            .setDiscountAmount(discountAmount)
                             .setTotalPower(totalPower)
                             .setAvgOrderElec(avgPower)
                             .setAvgOrderMoney((int) avgOrderMoney)

+ 17 - 2
common/src/main/java/com/kym/common/utils/CommUtil.java

@@ -10,6 +10,9 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
 
 
 /**
@@ -226,7 +229,7 @@ public class CommUtil {
     }
 
     public static String null2String(Object val) {
-        if(isEmptyOrNull(val)){
+        if (isEmptyOrNull(val)) {
             return "";
         }
         return val.toString().trim();
@@ -238,10 +241,22 @@ public class CommUtil {
         for (char ch : chars) {
             if (Character.isUpperCase(ch)) {
                 sbr.append("_").append(Character.toLowerCase(ch));
-            }else{
+            } else {
                 sbr.append(ch);
             }
         }
         return sbr.toString();
     }
+
+    /**
+     * 根据指定字段去重
+     *
+     * @param keyExtractor
+     * @param <T>
+     * @return
+     */
+    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
+        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
+    }
 }