EvalGroupTask.java 7.24 KB
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<StageIndicatorBO> 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<EvalGroupUser> users = evalGroupUserService.list(Wrappers.<EvalGroupUser>lambdaQuery()
                .eq(EvalGroupUser::getEvalGroupId, stageIndicator.getEvalGroupId())
                .eq(EvalGroupUser::getDataDate, localDate)
                .eq(EvalGroupUser::getYn, Boolean.TRUE)
        );
        List<Long> userIds = users.stream().map(EvalGroupUser::getUserId).distinct().collect(Collectors.toList());

        List<EvalGroupRewardDim> rewardDims = evalGroupRewardDimService.list(Wrappers.<EvalGroupRewardDim>lambdaQuery()
                .eq(EvalGroupRewardDim::getEvalGroupId, stageIndicator.getEvalGroupId())
                .eq(EvalGroupRewardDim::getType, EvalScopeEnum.SHOP)
                .eq(EvalGroupRewardDim::getYn, Boolean.TRUE)
        );
        List<Long> 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<EvalGroupRank> evalGroupRanks = evalGroupRankService.list(Wrappers.<EvalGroupRank>lambdaQuery()
                    .eq(EvalGroupRank::getStatus, SettingStatusEnum.EFFECTIVE)
                    .eq(EvalGroupRank::getYn, Boolean.TRUE)
            );
            if (PublicUtil.isEmpty(evalGroupRanks)) {
                return;
            }
            List<EvalGroupRank> ineffectiveRanks = new ArrayList<>();
            for  (EvalGroupRank evalGroupRank : evalGroupRanks) {
                List<EvalGroupRankStage> stages = evalGroupRankStageService.list(Wrappers.<EvalGroupRankStage>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();
        }
    }

}