package cn.fw.morax.server.task; import cn.fw.common.cache.locker.DistributedLocker; import cn.fw.morax.common.constant.TimeTaskConstant; import cn.fw.morax.common.utils.DateUtil; import cn.fw.morax.common.utils.PublicUtil; import cn.fw.morax.domain.bo.StageIndicatorBO; import cn.fw.morax.domain.db.eval.*; import cn.fw.morax.domain.db.kpi.KpiStageMqLog; import cn.fw.morax.domain.enums.EvalScopeEnum; import cn.fw.morax.domain.enums.SettingStatusEnum; import cn.fw.morax.sdk.dto.kpi.KpiStageReportNoticeMQ; import cn.fw.morax.service.component.KpiStageIndicatorReportProducer; import cn.fw.morax.service.data.eval.*; import cn.fw.morax.service.data.kpi.KpiStageMqLogService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.time.LocalDate; import java.util.*; import java.util.concurrent.locks.Lock; import java.util.stream.Collectors; /** * @author : jiangchao * @className : EvalGroupStatusTask * @description : 考评组配置状态定时器 * @date : 2022-04-07 15:29 */ @Component @Slf4j @RequiredArgsConstructor @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on") public class EvalGroupTask { private final EvalGroupIndicatorService evalGroupIndicatorService; private final EvalGroupRankStageService evalGroupRankStageService; private final EvalShopPoolService evalShopPoolService; private final EvalGroupRewardDimService evalGroupRewardDimService; private final EvalGroupUserService evalGroupUserService; private final KpiStageMqLogService kpiStageMqLogService; private final EvalGroupRankService evalGroupRankService; private final DistributedLocker distributedLocker; private final EvalGroupService evalGroupService; private final KpiStageIndicatorReportProducer kpiStageIndicatorReportProducer; @Value("${spring.cache.custom.global-prefix}:eval:group") @Getter private String evalGroupDistKey; @Value("${spring.cache.custom.global-prefix}:eval:group:rank") @Getter private String evalGroupRankKey; /** * 发送业务上报mq通知 */ @Scheduled(cron = TimeTaskConstant.EVAL_GROUP_REPORT_MQ) public void sendNotice() { final String lockKey = ":kpiSendNotice"; Lock lock = distributedLocker.lock(lockKey); if (((RLock) lock).isLocked()) { LocalDate lastDate = LocalDate.now().minusDays(1); List evalGroupRankStages = evalGroupIndicatorService.getStageIndicators(lastDate); if (CollectionUtils.isEmpty(evalGroupRankStages)) { return; } for (StageIndicatorBO stageIndicator : evalGroupRankStages) { try { sendNotice(stageIndicator, lastDate); } catch (Exception e) { log.error("发送绩效阶段上报mq失败: [{}]", stageIndicator, e); } } lock.unlock(); } } /** * 发送绩效数据上报mq * * @param localDate */ @Transactional(rollbackFor = Exception.class) public void sendNotice(StageIndicatorBO stageIndicator, final LocalDate localDate) { KpiStageMqLog mqLog = new KpiStageMqLog(); mqLog.setIndicatorCode(stageIndicator.getIndicatorCode()); mqLog.setBeginTime(stageIndicator.getBeginTime()); mqLog.setEndTime(localDate); mqLog.setEvalGroupId(stageIndicator.getEvalGroupId()); mqLog.setEvalGroupRankId(stageIndicator.getEvalGroupRankId()); mqLog.setGroupId(stageIndicator.getGroupId()); List users = evalGroupUserService.list(Wrappers.lambdaQuery() .eq(EvalGroupUser::getEvalGroupId, stageIndicator.getEvalGroupId()) .eq(EvalGroupUser::getDataDate, localDate) .eq(EvalGroupUser::getYn, Boolean.TRUE) ); List userIds = users.stream().map(EvalGroupUser::getUserId).distinct().collect(Collectors.toList()); List rewardDims = evalGroupRewardDimService.list(Wrappers.lambdaQuery() .eq(EvalGroupRewardDim::getEvalGroupId, stageIndicator.getEvalGroupId()) .eq(EvalGroupRewardDim::getType, EvalScopeEnum.SHOP) .eq(EvalGroupRewardDim::getYn, Boolean.TRUE) ); List shopIds = rewardDims.stream().flatMap(dim -> dim.getShopIds().stream()).distinct().collect(Collectors.toList()); if (PublicUtil.isEmpty(userIds) && PublicUtil.isEmpty(shopIds)) { return; } mqLog.setShopIds(shopIds); mqLog.setUserIds(userIds); kpiStageMqLogService.save(mqLog); kpiStageIndicatorReportProducer.send(KpiStageReportNoticeMQ.builder() .indicatorCode(stageIndicator.getIndicatorCode()) .beginTime(DateUtil.localDateTime2Date(mqLog.getBeginTime().atTime(0,0,1))) .endTime(DateUtil.localDateTime2Date(mqLog.getEndTime().atTime(23,59,59))) .shopIds(mqLog.getShopIds()) .userIds(mqLog.getUserIds()) .uid(mqLog.getId().toString()) .build()); } /** * 每月考评排名组配置状态改变 */ @Scheduled(cron = TimeTaskConstant.EVAL_GROUP_RANK_STATUS) @Transactional(rollbackFor = Exception.class) public void processCurMonthRanks() { Lock lock = distributedLocker.lock(getEvalGroupRankKey()); if (! ((RLock) lock).isLocked()) { return; } try { LocalDate currentTime = LocalDate.now(); List evalGroupRanks = evalGroupRankService.list(Wrappers.lambdaQuery() .eq(EvalGroupRank::getStatus, SettingStatusEnum.EFFECTIVE) .eq(EvalGroupRank::getYn, Boolean.TRUE) ); if (PublicUtil.isEmpty(evalGroupRanks)) { return; } List ineffectiveRanks = new ArrayList<>(); for (EvalGroupRank evalGroupRank : evalGroupRanks) { List stages = evalGroupRankStageService.list(Wrappers.lambdaQuery() .eq(EvalGroupRankStage::getEvalGroupRankId, evalGroupRank.getId()) .eq(EvalGroupRankStage::getYn, Boolean.TRUE) ); Boolean effective = stages.stream() .filter(evalGroup -> evalGroup.getOverTime().isBefore(currentTime)).findFirst().isPresent(); if (! effective) { evalGroupRank.setStatus(SettingStatusEnum.INEFFECTIVE); ineffectiveRanks.add(evalGroupRank); } } } catch (Exception e){ log.error(e.getMessage(), e); } finally { lock.unlock(); } } }