| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package com.kym.admin.jobs;
- import cn.hutool.core.date.DateUtil;
- import com.kym.common.utils.CommUtil;
- import com.kym.entity.admin.ConnectorInfo;
- import com.kym.entity.admin.StationStatDay;
- import com.kym.entity.admin.StationStatMonth;
- import com.kym.entity.miniapp.ChargeOrder;
- 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 lombok.extern.slf4j.Slf4j;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.time.LocalTime;
- import java.time.temporal.TemporalAdjusters;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * 站点统计定时任务
- *
- * @author skyline
- */
- @Component
- @Slf4j
- public class StationStatJob {
- private final ChargeOrderService chargeOrderService;
- private final StationStatDayService dayService;
- private final StationStatMonthService monthService;
- private final ConnectorInfoService connectorInfoService;
- public StationStatJob(ChargeOrderService chargeOrderService, StationStatDayService stationStatDayService, StationStatMonthService stationStatMonthService, ConnectorInfoService connectorInfoService) {
- this.chargeOrderService = chargeOrderService;
- this.dayService = stationStatDayService;
- this.monthService = stationStatMonthService;
- this.connectorInfoService = connectorInfoService;
- }
- // 每天14:30执行一次,通过charge_app.t_charge_order表统计start_time为前一天且充电金额大于100的充电订单,分别统计充电人数、订单数、充电总费用、充电总电量、平均充电电量、平均充电费用、平均订单费用、平均订单电量
- /**
- * 日统计,每日下午14:30启动,统计上日数据
- */
- // @Scheduled(cron = "0 30 14 * * ?")
- // 定时每日下午14:30
- private void dayStat() {
- log.info("执行站点日统计定时任务-开始");
- var statDay = LocalDateTime.now().minusDays(1);
- var startTime = LocalDateTime.of(statDay.toLocalDate(), LocalTime.MIN);
- var endTime = LocalDateTime.of(statDay.toLocalDate(), LocalTime.MAX);
- var chargeOrderList = getChargeOrders(startTime, endTime);
- dayService.saveBatch((Collection<StationStatDay>) getStationStat(chargeOrderList, true));
- log.info("执行站点日统计定时任务-结束");
- }
- /**
- * 月统计,每月第一天下午15:00启动,统计上月数据
- */
- // @Scheduled(cron = "0 0 15 1 * ?")
- private void monthStat() {
- log.info("执行站点月统计定时任务-开始");
- var statMonth = LocalDateTime.now().minusMonths(1);
- var startTime = statMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
- var endTime = statMonth.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
- var chargeOrderList = getChargeOrders(startTime, endTime);
- monthService.saveBatch((Collection<StationStatMonth>) getStationStat(chargeOrderList, false));
- 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为前一天且充电金额大于0的有效充电订单
- var res = chargeOrderService.lambdaQuery()
- .ge(ChargeOrder::getStartTime, startTime)
- .le(ChargeOrder::getStartTime, endTime)
- .gt(ChargeOrder::getTotalMoney, 0)
- .list();
- return res;
- }
- private Collection<?> getStationStat(List<ChargeOrder> chargeOrderList, boolean isDayStat) {
- // 统计每个站点的connector_id数量
- var stationConnectorCountMap = connectorInfoService.list().stream().collect(Collectors.groupingBy(ConnectorInfo::getStationId, Collectors.counting()));
- // 将chargeOrderList按照stationId分组
- var chargeOrderMap = chargeOrderList.stream().collect(Collectors.groupingBy(ChargeOrder::getStationId));
- // 根据分组计算每个站点的充电人数、订单数、充电总费用、充电总电量、平均充电电量、平均充电费用、平均订单费用、平均订单电量
- return chargeOrderMap.entrySet().stream().collect(Collectors.toMap(
- Map.Entry::getKey,
- entry -> {
- var chargeOrders = entry.getValue();
- var chargeUsers = chargeOrders.stream().collect(Collectors.collectingAndThen(
- Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ChargeOrder::getUserId))), ArrayList<ChargeOrder>::new)).size();
- 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())
- .setStatDay(DateUtil.format(LocalDateTime.now().minusDays(1), "yyyy-MM-dd"))
- .setChargeUsers(chargeUsers)
- .setValidOrders(chargeOrders.size())
- .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"))
- .setChargeUsers(chargeUsers)
- .setValidOrders(chargeOrders.size())
- .setTotalMoney(totalMoney)
- .setElecMoney(elecMoney)
- .setServiceMoney(serviceMoney)
- .setServiceMoneyDiscount(serviceMoneyDiscount)
- .setDiscountAmount(discountAmount)
- .setTotalPower(totalPower)
- .setAvgOrderElec(avgPower)
- .setAvgOrderMoney((int) avgOrderMoney)
- .setAvgConnectorElec(totalPower / (stationConnectorCountMap.get(entry.getKey()) * (LocalDate.now().minusMonths(1).lengthOfMonth())));
- })).values();
- }
- }
|