FollowRecordTask.java 8.57 KB
package cn.fw.valhalla.controller.task;

import cn.fw.valhalla.common.utils.DateUtil;
import cn.fw.valhalla.common.utils.StringUtils;
import cn.fw.valhalla.domain.db.follow.FollowRecord;
import cn.fw.valhalla.domain.db.follow.FollowTask;
import cn.fw.valhalla.domain.enums.FollowTypeEnum;
import cn.fw.valhalla.domain.enums.TaskStateEnum;
import cn.fw.valhalla.domain.vo.follow.*;
import cn.fw.valhalla.rpc.backlog.TodoRpcService;
import cn.fw.valhalla.rpc.backlog.dto.BackLogItemDTO;
import cn.fw.valhalla.service.bus.follow.FollowBizService;
import cn.fw.valhalla.service.data.FollowRecordService;
import cn.fw.valhalla.service.data.FollowTaskService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.LocalDateTime;
import java.util.*;

/**
 * @author : kurisu
 * @className : FollowRecordTask
 * @description : 跟进任务定时任务
 * @date: 2020-08-25 16:56
 */
@Component
@Slf4j
@ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
public class FollowRecordTask {
    private final FollowRecordService followRecordService;
    private final FollowBizService followBizService;
    private final TodoRpcService todoRpcService;
    private final FollowTaskService followTaskService;


    @Value("${follow.todo.FMCode}")
    @Getter
    private String FMCode;

    @Value("${follow.todo.RMCode}")
    @Getter
    private String RMCode;

    @Value("${follow.todo.IRCode}")
    @Getter
    private String IRCode;

    @Value("${follow.todo.ACCode}")
    @Getter
    private String ACCode;

    @Autowired
    public FollowRecordTask(final FollowRecordService followRecordService,
                            final FollowBizService followBizService,
                            final TodoRpcService todoRpcService,
                            final FollowTaskService followTaskService) {
        this.followRecordService = followRecordService;
        this.followBizService = followBizService;
        this.todoRpcService = todoRpcService;
        this.followTaskService = followTaskService;
    }

    /**
     * 处理跟进逾期
     */
    @Scheduled(initialDelay = 1000 * 15, fixedRate = 1000 * 5)
    @Transactional(rollbackFor = Exception.class)
    public void endTaskRecord() {
        List<FollowRecord> list = followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                .eq(FollowRecord::getOutTime, Boolean.FALSE)
                .le(FollowRecord::getDeadline, DateUtil.localDateTime2Date(LocalDateTime.now()))
                .isNull(FollowRecord::getFollowTime)
                .last("limit 0, 500")
        );
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (FollowRecord record : list) {
            followBizService.overdueProcessing(record);
        }
    }

    /**
     * 普通待办指定时间才推送
     * 推送到待办系统
     */
    @Scheduled(cron = "0/8 30/1 8-18 * * *")
    @Transactional(rollbackFor = Exception.class)
    public void push2NorTodo() {
        List<FollowRecord> list = followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                .eq(FollowRecord::getOutTime, Boolean.FALSE)
                .eq(FollowRecord::getAddTodo, Boolean.FALSE)
                .ne(FollowRecord::getType, FollowTypeEnum.AC)
                .le(FollowRecord::getPlanTime, DateUtil.localDateTime2Date(LocalDateTime.now()))
                .last("limit 0,500")
        );
        execute(list);
    }

    /**
     * 事故车待办随时推送
     * 推送到待办系统
     */
    @Scheduled(initialDelay = 1500, fixedRate = 1000 * 3)
    @Transactional(rollbackFor = Exception.class)
    public void push2AccTodo() {
        List<FollowRecord> list = followRecordService.list(Wrappers.<FollowRecord>lambdaQuery()
                .eq(FollowRecord::getOutTime, Boolean.FALSE)
                .eq(FollowRecord::getType, FollowTypeEnum.AC)
                .eq(FollowRecord::getAddTodo, Boolean.FALSE)
                .le(FollowRecord::getPlanTime, DateUtil.localDateTime2Date(LocalDateTime.now()))
                .last("limit 0,50")
        );
        execute(list);
    }

    /**
     * 完成待办的重试
     */
    @Scheduled(initialDelay = 1500, fixedRate = 15 * 1000)
    public void retryCompleteTodoItem() {
        String key = todoRpcService.generateKey(TodoRpcService.TodoOperationEnum.COMPLETE);
        Collection<BackLogItemDTO> all = todoRpcService.getAllFromCache(key);
        all.forEach(todoRpcService::complete);
    }

    /**
     * 取消待办的重试
     */
    @Scheduled(initialDelay = 1000, fixedRate = 10 * 1000)
    public void retryCancelTodoItem() {
        String key = todoRpcService.generateKey(TodoRpcService.TodoOperationEnum.CANCEL);
        Collection<BackLogItemDTO> all = todoRpcService.getAllFromCache(key);
        all.forEach(todoRpcService::cancel);
    }


    private void execute(List<FollowRecord> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<Long> idList = new ArrayList<>();
        List<Long> failIdList = new ArrayList<>();
        for (FollowRecord record : list) {
            FollowTask task = followTaskService.getById(record.getTaskId());
            if (Objects.nonNull(task) && TaskStateEnum.ONGOING.equals(task.getState())) {
                try {
                    BackLogItemDTO dto = new BackLogItemDTO(record.getUserId(), getItemCode(record.getType()), String.valueOf(record.getId()), record.getPlanTime(), record.getShopId());
                    dto.setExpireTime(record.getDeadline());
                    dto.setDynamicMap(create(record));
                    todoRpcService.push(dto);
                    idList.add(record.getId());
                } catch (Exception e) {
                    log.error("推送待办失败,dataId:{}", record.getId(), e);
                }
            } else {
                failIdList.add(record.getId());
            }
        }
        followRecordService.addTodoBatchById(idList);
        if (!CollectionUtils.isEmpty(failIdList)) {
            followRecordService.removeByIds(failIdList);
        }
    }

    private Map<String, String> create(FollowRecord record) {
        FollowDetailVO vo = followBizService.todoDetail(record.getId(), record.getType());
        Map<String, String> dynamicMap = new HashMap<>();
        dynamicMap.put("type", record.getType().getValue().toString());
        dynamicMap.put("taskId", record.getTaskId().toString());
        dynamicMap.put("id", record.getId().toString());
        if (Objects.nonNull(vo)) {
            dynamicMap.put("state", "1");
            dynamicMap.put("plateNo", StringUtils.isValid(vo.getPlateNo()) ? vo.getPlateNo() : "-");
            dynamicMap.put("name", StringUtils.isValid(vo.getName()) ? vo.getName() : "-");
            if (vo instanceof FMDetailVO) {
                dynamicMap.put("buyDate", DateUtil.getFullDateString(((FMDetailVO) vo).getBuyDate(), "-"));
                dynamicMap.put("expirTime", DateUtil.getFullDateString(((FMDetailVO) vo).getFMExpiration(), "-"));
            } else if (vo instanceof RMDetailVO) {
                dynamicMap.put("currentMileage", Optional.ofNullable(((RMDetailVO) vo).getLastMileage()).map(String::valueOf).orElse("-"));
                dynamicMap.put("arrivalTime", DateUtil.getFullDateString(((RMDetailVO) vo).getDeliveryTime(), "-"));
            } else if (vo instanceof IRDetailVO) {
                dynamicMap.put("expirTime", DateUtil.getFullDateString(((IRDetailVO) vo).getTclInsExpiration(), "-"));
                dynamicMap.put("insComName", StringUtils.isValid(((IRDetailVO) vo).getTclInsComName()) ? vo.getPlateNo() : "-");
            } else if (vo instanceof ACDetailVO) {
                dynamicMap.put("insComName", StringUtils.isValid(((ACDetailVO) vo).getInsComName()) ? vo.getPlateNo() : "-");
            }
        }
        return dynamicMap;
    }

    private String getItemCode(FollowTypeEnum type) {
        switch (type) {
            case AC:
                return getACCode();
            case FM:
                return getFMCode();
            case IR:
                return getIRCode();
            case RM:
                return getRMCode();
            default:
                return getFMCode();
        }
    }

}