liujie
1 天以前 6406a54f7d2b67b46eae0e7987900974b34be5d7
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/EnergyRefreshService.java
@@ -30,81 +30,134 @@
    private TSystemConfigurationMapper systemConfigurationMapper;
    // 储能相关参数
    private final BigDecimal storageMaxMorning = new BigDecimal("115"); // 凌晨到8点储能最大值
    private final BigDecimal storageMaxAfternoon = new BigDecimal("115"); // 12点后储能最大值
    private final BigDecimal dischargeMaxMorning = new BigDecimal("90"); // 上午放电最大值
    private final BigDecimal dischargeMaxAfternoon = new BigDecimal("90"); // 下午放电最大值
    private final BigDecimal storageMax = new BigDecimal("115"); // 储能最大值
    private final BigDecimal targetDischargeTotal = new BigDecimal("97.75"); // 目标总放电量
    private final double minChargeIncrement = 0.5; // 充电最小增量
    private final double maxChargeIncrement = 1.0; // 充电最大增量
    private final int minDischargeTimes = 3; // 最小放电次数
    private final int maxDischargeTimes = 4; // 最大放电次数
    private final BigDecimal minDischargeAmount = new BigDecimal("25"); // 单次最小放电量
    private final BigDecimal maxDischargeAmount = new BigDecimal("35"); // 单次最大放电量
    private final double minIncrement = 0.5; // 最小增量(储能/放电共用)
    private final double maxIncrement = 1.0; // 最大增量(储能/放电共用)
    // 充电阶段标记
    private boolean isFirstChargeCompleted = false;
    private boolean isSecondChargeCompleted = false;
    // 放电次数计数器
    private int dischargeCount = 0;
    // 当前阶段总放电量
    private BigDecimal currentPhaseDischarge = BigDecimal.ZERO;
    // 定时任务方法 - 能量刷新
    @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次(原15分钟改为1分钟)
    @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次
    public synchronized void refreshValue() {
        LocalTime now = LocalTime.now();
        // 根据时间段执行不同逻辑
        if (isInStorageMorning(now)) { // 00:00-7:59 储能阶段
            handleStoragePhase(storageMaxMorning, BigDecimal.ZERO);
        } else if (isInDischargeMorning(now)) { // 10:00-11:59 上午放电阶段
            handleDischargePhase(dischargeMaxMorning);
        } else if (isInStorageAfternoon(now)) { // 12:00-16:59 下午储能阶段
            handleStoragePhase(storageMaxAfternoon, getTodayDischarge());
        } else if (isInDischargeAfternoon(now)) { // 17:00-21:59 下午放电阶段
            handleDischargePhase(dischargeMaxAfternoon);
        // 第一轮充电阶段 (0:00-3:00)
        if (now.isAfter(LocalTime.of(0, 0)) && now.isBefore(LocalTime.of(3, 0))) {
            handleChargePhase();
        }
        // 第一轮放电阶段 (3:10开始,每10分钟一次)
        else if (now.isAfter(LocalTime.of(3, 0)) && now.isBefore(LocalTime.of(15, 0))
                && now.getMinute() % 10 == 0 && now.getSecond() == 0) {
            handleDischargePhase(false);
        }
        // 第二轮充电阶段 (15:00-17:00)
        else if (now.isAfter(LocalTime.of(15, 0)) && now.isBefore(LocalTime.of(17, 0))) {
            handleChargePhase();
        }
        // 第二轮放电阶段 (17:10开始,每10分钟一次)
        else if (now.isAfter(LocalTime.of(17, 0)) && now.isBefore(LocalTime.of(23, 59))
                && now.getMinute() % 10 == 0 && now.getSecond() == 0) {
            handleDischargePhase(true);
        }
    }
    // 储能阶段处理逻辑
    public void handleStoragePhase(BigDecimal maxValue, BigDecimal dischargeValue) {
        BigDecimal todayStorage=getTodayStorage();//当前储能值
        BigDecimal availableSpace = maxValue.subtract(todayStorage.subtract(dischargeValue));//115-(储能-放能) 当前可上涨空间
    // 充电阶段处理逻辑
    private void handleChargePhase() {
        BigDecimal todayStorage = getTodayStorage();
        // 随机增量0.5—1.0
        BigDecimal increment = randomBigDecimal(minIncrement,maxIncrement);
        BigDecimal newStorage;
        if (availableSpace.compareTo(increment) >= 0 ) {
            //可用空间大于等于当前增量
             newStorage = todayStorage.add(increment)
                    .setScale(2, RoundingMode.HALF_UP);
        }else {
            //可用空间不足当前增量
            newStorage = maxValue.add(dischargeValue);//115 + 放能  (如:上午放90,下午就只能充90)
        // 如果已经充满,则不再充电
        if (todayStorage.compareTo(storageMax) >= 0) {
            if (!isFirstChargeCompleted && todayStorage.compareTo(storageMax) >= 0) {
                isFirstChargeCompleted = true;
                System.out.println("第一轮充电已完成,当前储能: " + todayStorage);
            } else if (!isSecondChargeCompleted && todayStorage.compareTo(storageMax.multiply(new BigDecimal("2"))) >= 0) {
                isSecondChargeCompleted = true;
                System.out.println("第二轮充电已完成,当前储能: " + todayStorage);
        }
        if (newStorage.compareTo(todayStorage)==0){
            //新增值等于当前储能值 说明已达到最大值,没必要更新了
            return;
        }
        // 随机增量0.5-1.0
        BigDecimal increment = randomBigDecimal(minChargeIncrement, maxChargeIncrement);
        BigDecimal newStorage = todayStorage.add(increment).setScale(2, RoundingMode.HALF_UP);
        // 确保不超过最大值
        BigDecimal maxAllowed = isFirstChargeCompleted ? storageMax.multiply(new BigDecimal("2")) : storageMax;
        if (newStorage.compareTo(maxAllowed) > 0) {
            newStorage = maxAllowed;
        }
        updateStorageValue(newStorage);
        System.out.printf("储能阶段:当前时间 %s,今日储能:%.2f%n", LocalTime.now(), newStorage);
        System.out.printf("充电阶段:当前时间 %s,今日储能:%.2f%n", LocalTime.now(), newStorage);
    }
    // 放电阶段处理逻辑
    private void handleDischargePhase(BigDecimal maxDischarge) {
        BigDecimal currentDischarge = getTodayDischarge();//当前放电量
        BigDecimal todayStorage = getTodayStorage();//储能量
        //今日储能-115,就是耗能(基数),在这个基数上加90
        BigDecimal baseDischarge = todayStorage.subtract(storageMaxAfternoon);
        BigDecimal newMaxDischarge = baseDischarge.add(maxDischarge);//上限 基数+90
        // 随机增量0.5—1.0
        BigDecimal increment = randomBigDecimal(minIncrement,maxIncrement);
        BigDecimal newDischarge = currentDischarge.add(increment);//当前值 + 增量
        if (newDischarge.compareTo(newMaxDischarge) >=0) {
            //超出 用最大值
            newDischarge = newMaxDischarge;
        }
        if (newDischarge.compareTo(currentDischarge)==0){
            //新增值等于当前值,说明已超出,没必要更新了
    private void handleDischargePhase(boolean isSecondPhase) {
        // 如果是第二轮放电且第一轮未完成,则不执行
        if (isSecondPhase && !isFirstChargeCompleted) {
            return;
        }
        // 如果已经达到目标放电量,则不再放电
        BigDecimal todayDischarge = getTodayDischarge();
        BigDecimal target = isSecondPhase ? targetDischargeTotal.multiply(new BigDecimal("2")) : targetDischargeTotal;
        if (todayDischarge.compareTo(target) >= 0) {
            return;
        }
        // 如果是新一轮放电阶段,重置计数器
        if (currentPhaseDischarge.compareTo(BigDecimal.ZERO) == 0) {
            dischargeCount = 0;
        }
        // 计算剩余需要放电的量
        BigDecimal remainingDischarge = target.subtract(todayDischarge);
        // 随机本次放电量 (25-35)
        BigDecimal dischargeAmount = randomBigDecimal(minDischargeAmount.doubleValue(), maxDischargeAmount.doubleValue());
        // 如果剩余量不足,则只放剩余量
        if (dischargeAmount.compareTo(remainingDischarge) > 0) {
            dischargeAmount = remainingDischarge;
        }
        // 更新放电量
        BigDecimal newDischarge = todayDischarge.add(dischargeAmount).setScale(2, RoundingMode.HALF_UP);
        updateDischargeValue(newDischarge);
        System.out.printf("放电阶段:当前时间 %s,今日放电:%.2f%n", LocalTime.now(), newDischarge);
        // 更新当前阶段放电总量
        currentPhaseDischarge = currentPhaseDischarge.add(dischargeAmount);
        dischargeCount++;
        System.out.printf("放电阶段:当前时间 %s,第%d次放电,本次放电:%.2f,今日总放电:%.2f%n",
                LocalTime.now(), dischargeCount, dischargeAmount, newDischarge);
        // 如果达到最大放电次数或完成目标放电量,重置当前阶段放电量
        if (dischargeCount >= maxDischargeTimes || remainingDischarge.subtract(dischargeAmount).compareTo(BigDecimal.ZERO) <= 0) {
            currentPhaseDischarge = BigDecimal.ZERO;
        }
    }
    // 重置任务(每天凌晨0点)
    @Scheduled(cron = "0 0 0 * * ?")
    public void reset() {
        // 重置所有状态
        isFirstChargeCompleted = false;
        isSecondChargeCompleted = false;
        dischargeCount = 0;
        currentPhaseDischarge = BigDecimal.ZERO;
        // 初始化今日储能和放电为0
        updateStorageValue(BigDecimal.ZERO);
        updateDischargeValue(BigDecimal.ZERO);
@@ -136,15 +189,7 @@
        // 转换为两位小数的 BigDecimal
        return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP);
    }
    // 更新今日储能值到数据库
    private void updateStorageValue(BigDecimal value) {
        updateConfigField("todayStorage", value);
    }
    // 更新今日放电值到数据库(原逻辑保留)
    private void updateDischargeValue(BigDecimal value) {
        updateConfigField("todayDischarge", value);
    }
    // 通用配置更新方法
    private void updateConfigField(String field, BigDecimal value) {
@@ -180,6 +225,17 @@
        return time.isAfter(LocalTime.of(17, 0)) && time.isBefore(LocalTime.of(22, 0));
    }
    // 更新今日储能值到数据库
    private void updateStorageValue(BigDecimal value) {
        updateConfigField("todayStorage", value);
    }
    // 更新今日放电值到数据库(原逻辑保留)
    private void updateDischargeValue(BigDecimal value) {
        updateConfigField("todayDischarge", value);
    }
    public BigDecimal getTodayStorage() {
        TSystemConfiguration sysConfig = systemConfigurationMapper.selectOne(
                new LambdaQueryWrapper<TSystemConfiguration>()