吉安感知网项目-后端
xiebin
2026-01-19 4e48664942bbefe70699ca43d25cbbd56ecc8daa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package org.sxkj.fw.device.scheduler;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.sxkj.common.utils.DateUtils;
import org.sxkj.fw.device.entity.FwDeviceMaintainPlanEntity;
import org.sxkj.fw.device.service.IFwDeviceMaintainPlanService;
import org.sxkj.fw.device.service.IFwDeviceMaintainRecordService;
 
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
/**
 * @Description 设备维护计划状态更新定时器
 * @Author AIX
 * @Date 2026/1/19 11:34
 * @Version 1.0
 */
@Component
@Slf4j
@AllArgsConstructor
public class MaintainPlanScheduler {
 
    private final IFwDeviceMaintainPlanService fwDeviceMaintainPlanService;
 
    @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨0点执行
    // 每10秒执行一次
//    @Scheduled(cron = "*/10 * * * * ?") // 每10秒执行一次,用于本地调试
    public void refreshMaintainStatus() {
        log.info("开始执行设备维护计划状态刷新任务");
 
        try {
            // 获取所有有效的维护计划
            List<FwDeviceMaintainPlanEntity> plans = fwDeviceMaintainPlanService.list();
 
            Date currentTime = new Date();
            List<Long> expiredPlanIds = new ArrayList<>();
 
            // 先收集需要更新的计划ID
            for (FwDeviceMaintainPlanEntity plan : plans) {
                boolean isExpired = checkPlanExpired(plan, currentTime);
 
                if (isExpired && plan.getMaintainStatus() != null && plan.getMaintainStatus() == 1) {
                    expiredPlanIds.add(plan.getId());
                }
            }
 
            // 批量更新数据库
            if (!expiredPlanIds.isEmpty()) {
                fwDeviceMaintainPlanService.batchUpdateExpiredPlans(expiredPlanIds);
                log.info("批量更新 {} 个过期计划状态为未维护", expiredPlanIds.size());
            }
 
            log.info("设备维护计划状态刷新任务完成,共处理 {} 条计划,更新 {} 条过期计划", plans.size(), expiredPlanIds.size());
        } catch (Exception e) {
            log.error("设备维护计划状态刷新任务执行失败", e);
        }
    }
 
    /**
     * 检查维护计划是否已过期
     */
    private boolean checkPlanExpired(FwDeviceMaintainPlanEntity plan, Date currentTime) {
        String planCycleType = plan.getPlanCycleType();
 
        // 如果从未维护过,且计划周期已过,则认为已过期
        if (plan.getLastMaintainTime() == null) {
            return true;
        }
 
        LocalDateTime currentDateTime = currentTime.toInstant()
                .atZone(ZoneId.of("Asia/Shanghai"))
                .toLocalDateTime();
 
        switch (planCycleType) {
            case "1":
                return checkAnnualPlanExpired(plan, currentDateTime);
            case "2":
                return checkMonthlyPlanExpired(plan, currentDateTime);
            case "3":
                return checkWeeklyPlanExpired(plan, currentDateTime);
            default:
                return false;
        }
    }
 
    /**
     * 检查年度计划是否过期
     */
    private boolean checkAnnualPlanExpired(FwDeviceMaintainPlanEntity plan, LocalDateTime currentDateTime) {
        List<String> planCycleValue = plan.getPlanCycleValue();
        Date lastMaintainTime = plan.getLastMaintainTime();
 
        for (String ruleValue : planCycleValue) {
            String[] parts = ruleValue.split("月");
            int ruleMonth = Integer.parseInt(parts[0]);
            int ruleDay = Integer.parseInt(parts[1].replace("号", ""));
 
            LocalDateTime[] cycleBounds = DateUtils.calculateAnnualCycle(lastMaintainTime, ruleMonth, ruleDay);
            LocalDateTime nextCycleStart = cycleBounds[1]; // 下一周期开始时间
 
            if (currentDateTime.isAfter(nextCycleStart)) {
                return true;
            }
        }
        return false;
    }
 
    /**
     * 检查月度计划是否过期
     */
    private boolean checkMonthlyPlanExpired(FwDeviceMaintainPlanEntity plan, LocalDateTime currentDateTime) {
        List<String> planCycleValue = plan.getPlanCycleValue();
        Date lastMaintainTime = plan.getLastMaintainTime();
 
        for (String ruleValue : planCycleValue) {
            int ruleDay = Integer.parseInt(ruleValue.replace("号", ""));
 
            LocalDateTime[] cycleBounds = DateUtils.calculateMonthlyCycle(lastMaintainTime, ruleDay);
            LocalDateTime nextCycleStart = cycleBounds[1]; // 下一周期开始时间
 
            if (currentDateTime.isAfter(nextCycleStart)) {
                return true;
            }
        }
        return false;
    }
 
    /**
     * 检查周度计划是否过期
     */
    private boolean checkWeeklyPlanExpired(FwDeviceMaintainPlanEntity plan, LocalDateTime currentDateTime) {
        List<String> planCycleValue = plan.getPlanCycleValue();
        Date lastMaintainTime = plan.getLastMaintainTime();
 
        for (String ruleValue : planCycleValue) {
            int ruleDayOfWeek = DateUtils.getDayOfWeekNumber(ruleValue);
 
            LocalDateTime[] cycleBounds = DateUtils.calculateWeeklyCycle(lastMaintainTime, ruleDayOfWeek);
            LocalDateTime nextCycleStart = cycleBounds[1]; // 下一周期开始时间
 
            if (currentDateTime.isAfter(nextCycleStart)) {
                return true;
            }
        }
        return false;
    }
 
}