| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- package com.yimeng.okr.schedule;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.yimeng.okr.entity.AssessmentPeriod;
- import com.yimeng.okr.entity.KrKeyResult;
- import com.yimeng.okr.entity.OkrObjective;
- import com.yimeng.okr.entity.SysUser;
- import com.yimeng.okr.enums.PeriodStatus;
- import com.yimeng.okr.event.NotificationEvent;
- import com.yimeng.okr.mapper.AssessmentPeriodMapper;
- import com.yimeng.okr.mapper.KrKeyResultMapper;
- import com.yimeng.okr.mapper.OkrObjectiveMapper;
- import com.yimeng.okr.mapper.SysUserMapper;
- import com.yimeng.okr.service.AssessmentPeriodService;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.context.ApplicationEventPublisher;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import java.time.LocalDate;
- import java.time.temporal.ChronoUnit;
- import java.util.List;
- @Slf4j
- @Component
- @RequiredArgsConstructor
- public class PeriodScheduler {
- private final AssessmentPeriodService periodService;
- private final AssessmentPeriodMapper periodMapper;
- private final SysUserMapper userMapper;
- private final OkrObjectiveMapper objectiveMapper;
- private final KrKeyResultMapper krMapper;
- private final ApplicationEventPublisher publisher;
- @Scheduled(cron = "0 0 2 * * ?")
- public void autoAdvancePeriods() {
- log.info("Running period auto-advance check...");
- periodService.checkAndAutoAdvance();
- }
- @Scheduled(cron = "0 0 10 * * ?")
- public void checkPeriodDeadlines() {
- log.info("Checking period deadlines...");
- List<AssessmentPeriod> periods = periodMapper.selectList(
- new LambdaQueryWrapper<AssessmentPeriod>()
- .eq(AssessmentPeriod::getStatus, PeriodStatus.EXECUTING));
- LocalDate today = LocalDate.now();
- for (AssessmentPeriod p : periods) {
- try {
- if (ChronoUnit.DAYS.between(today, p.getEndDate()) == 3) {
- List<SysUser> users = userMapper.selectList(null);
- for (SysUser u : users) {
- publisher.publishEvent(new NotificationEvent(
- this, u.getId(), "PERIOD_DEADLINE",
- "周期即将结束", "考核周期「" + p.getName() + "」将于3天后结束",
- "period", p.getId()));
- }
- }
- } catch (Exception e) {
- log.warn("Failed to check deadline for period {}: {}", p.getId(), e.getMessage());
- }
- }
- }
- @Scheduled(cron = "0 7 10 * * ?")
- public void checkKrLagging() {
- log.info("Checking KR lagging...");
- List<AssessmentPeriod> periods = periodMapper.selectList(
- new LambdaQueryWrapper<AssessmentPeriod>()
- .eq(AssessmentPeriod::getStatus, PeriodStatus.EXECUTING));
- LocalDate today = LocalDate.now();
- for (AssessmentPeriod p : periods) {
- try {
- long totalDays = ChronoUnit.DAYS.between(p.getStartDate(), p.getEndDate());
- if (totalDays <= 0) continue;
- long elapsedDays = ChronoUnit.DAYS.between(p.getStartDate(), today);
- if (elapsedDays < 3) continue; // ignore first 3 days
- double elapsedRatio = Math.min(1.0, (double) elapsedDays / totalDays);
- double expectedProgress = elapsedRatio * 100;
- List<OkrObjective> objectives = objectiveMapper.selectList(
- new LambdaQueryWrapper<OkrObjective>()
- .eq(OkrObjective::getPeriodId, p.getId())
- .eq(OkrObjective::getStatus, "APPROVED"));
- for (OkrObjective obj : objectives) {
- List<KrKeyResult> krs = krMapper.selectList(
- new LambdaQueryWrapper<KrKeyResult>()
- .eq(KrKeyResult::getObjectiveId, obj.getId()));
- for (KrKeyResult kr : krs) {
- if ("COMPLETED".equals(kr.getStatus())) continue;
- double actualProgress = kr.getTargetValue() > 0
- ? (kr.getCurrentValue() / kr.getTargetValue()) * 100 : 0;
- if (actualProgress < expectedProgress - 20) {
- publisher.publishEvent(new NotificationEvent(
- this, obj.getUserId(), "KR_LAGGING",
- "KR 进度滞后",
- "「" + kr.getTitle() + "」进度落后于时间线(当前 "
- + Math.round(actualProgress) + "%,预期 " + Math.round(expectedProgress) + "%),请及时更新",
- "objective", obj.getId()));
- }
- }
- }
- } catch (Exception e) {
- log.warn("Failed to check KR lagging for period {}: {}", p.getId(), e.getMessage());
- }
- }
- }
- }
|