xiangpei
2025-03-26 1b9936ba920d65df09ab8dba79c6252568ee26e4
business/src/main/java/com/ycl/task/FlowableTask.java
@@ -1,15 +1,21 @@
package com.ycl.task;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.ycl.common.enums.business.ProcessLogEventTypeEnum;
import com.ycl.common.enums.business.ProjectProcessTypeEnum;
import com.ycl.domain.entity.ProcessCoding;
import com.ycl.domain.entity.ProcessLog;
import com.ycl.domain.entity.ProjectInfo;
import com.ycl.domain.entity.ProjectProcess;
import com.ycl.factory.FlowServiceFactory;
import com.ycl.mapper.ProcessCodingMapper;
import com.ycl.mapper.ProcessLogMapper;
import com.ycl.mapper.ProjectInfoMapper;
import com.ycl.mapper.ProjectProcessMapper;
import com.ycl.service.ProcessCodingService;
import com.ycl.service.ProcessLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.task.api.Task;
@@ -24,6 +30,8 @@
import java.util.stream.Collectors;
import static com.ycl.common.constant.ProcessOverTimeConstants.*;
import static com.ycl.common.enums.business.ProcessLogEventTypeEnum.CANCEL_HANGUP;
import static com.ycl.common.enums.business.ProcessLogEventTypeEnum.HANGUP;
@Slf4j
@Component("flowableTask")
@@ -34,6 +42,10 @@
    private ProjectInfoMapper projectInfoMapper;
    @Autowired
    private ProcessCodingMapper processCodingMapper;
    @Autowired
    private ProcessLogService processLogService;
    @Autowired
    private ProcessLogMapper processLogMapper;
    /**
     * 赋码任务
@@ -42,11 +54,32 @@
    public void expireTask() {
        log.info("开始赋码");
        //当前正在运行的所有任务节点
        List<Task> taskList = taskService.createTaskQuery().list();
        List<Task> taskList = taskService.createTaskQuery().active().list();
        if (CollectionUtils.isEmpty(taskList)) return;
        //排除掉节点挂起的任务
        List<String> allHangupTask = processLogMapper.getAllHangup();
        taskList = taskList.stream()
                .filter(task -> !allHangupTask.contains(task.getId()))
                .collect(Collectors.toList());
        //TODO:筛选出流程实例id,用作项目挂起
        Set<String> proInsIds = taskList.stream()
                .map(TaskInfo::getProcessInstanceId)
                .collect(Collectors.toSet());
        //TODO:查询项目挂起日志
        List<String> taskIds = taskList.stream().map(TaskInfo::getId).collect(Collectors.toList());
        //查询节点挂起日志
        Map<String, List<ProcessLog>> hangupLogMap = new LambdaQueryChainWrapper<>(processLogMapper)
                .in(ProcessLog::getEventType, HANGUP, CANCEL_HANGUP)
                .in(ProcessLog::getProcessInsId, taskIds)
                .list()
                .stream()
                .collect(Collectors.groupingBy(ProcessLog::getTaskId));
        //需要监控的赋码任务
        List<ProcessCoding> processCodingList = processCodingMapper.selectList(new QueryWrapper<ProcessCoding>().in("task_id", taskIds));
        List<ProcessCoding> processCodingList = new LambdaQueryChainWrapper<>(processCodingMapper)
                .in(ProcessCoding::getTaskId, taskIds)
                .list();
        Map<String, ProcessCoding> taskMap = new HashMap<>();
        Map<String, Date> startTaskMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(processCodingList)) {
@@ -67,54 +100,50 @@
            String taskId = task.getId();
            ProcessCoding processCoding = taskMap.get(taskId);
            if (processCoding == null) {
                //不需要监控的任务节点直接改为绿色
                List<String> processInsIds = map.get(GREEN);
                processInsIds.add(task.getProcessInstanceId());
                //不需要监控的任务节点项目码直接改为绿色
                map.get(GREEN).add(task.getProcessInstanceId());
                continue;
            }
            //判断是否超时
            //判断赋码统一用秒作为单位,且只需用红码时间判断超时,通过超时去改变项目的赋码状态,节点本身无赋码状态
            Date startTime = startTaskMap.get(processCoding.getStartTaskId());
            try {
                Long yellowTime = null;
                Long redTime = null;
                String yellowTimeStr = processCoding.getYellowTime();
                if (StringUtils.isNotBlank(yellowTimeStr)) {
                    String[] yellowTimeArr = yellowTimeStr.split("-");
                    // 解析天数和小时数
                    int days = Integer.parseInt(yellowTimeArr[0]);
                    int hours = 0;
                    // 兼容之前配置的整数天
                    if (yellowTimeArr.length > 1) {
                        hours = Integer.parseInt(yellowTimeArr[1]);
                    }
                    yellowTime = (days * 24L + hours) * 3600L;
                }
                String redTimeStr = processCoding.getRedTime();
                if (StringUtils.isNotBlank(redTimeStr)) {
                    String[] redTimeArr = redTimeStr.split("-");
                    // 解析天数和小时数
                    int days = Integer.parseInt(redTimeArr[0]);
                    int hours = 0;
                    if (redTimeArr.length > 1) {
                        hours = Integer.parseInt(redTimeArr[1]);
                    }
                    redTime = (days * 24L + hours) * 3600L;
                }
                Long redTime = getTime(processCoding.getRedTime());
//                Long yellowTime = getTime(processCoding.getYellowTime());
//                Long overtime = getTime(processCoding.getOvertime());
                if (startTime == null) continue;
                long durationDay = (now.getTime() - startTime.getTime()) / 1000;
                //节点处理时间
                long durationTime = (now.getTime() - startTime.getTime()) / 1000;
                //TODO:减去流程挂起时长
                //减去节点挂起时长
                durationTime = subNodeHangupTime(hangupLogMap, task, durationTime);
                String status = GREEN; // 默认状态为绿色
                if (redTime != null && durationDay >= redTime) {
                    status = RED; // 如果超过红色时间阈值,则状态为红色
                } else if (yellowTime != null && durationDay >= yellowTime) {
                    status = YELLOW; // 否则,如果超过黄色时间阈值,则状态为黄色
                String overtimeStatus = NORMAL;
                if (redTime != null && redTime != 0 && durationTime >= redTime) {
                    status = RED; // 如果超过红色时间阈值,则表明该任务超时
                    overtimeStatus = OVERTIME;
                }
                List<String> processInsIds = map.get(status);
                processInsIds.add(task.getProcessInstanceId());
//                else if (yellowTime != null && yellowTime != 0 && durationTime >= yellowTime) {
//                    status = YELLOW; // 否则,如果超过黄色时间阈值,则状态为黄色
//                }
//                //处理办理期限
//                String overtimeStatus = NORMAL;
//                if (overtime != null && overtime != 0 && durationTime >= overtime) {
//                    overtimeStatus = OVERTIME; // 如果超过办理期限
//                } else if (overtime != null && overtime != 0 && durationTime >= (overtime - 12 * 60 * 60)) {
//                    overtimeStatus = WILLOVERTIME; // 如果临期(固定超时前12小时为临期)
//                }
//                else if (overtime != null && overtime != 0 && durationDay >= (overtime - 60)) {
//                    overtimeStatus = WILLOVERTIME; // 如果临期(固定超时前12小时为临期)
//                }
                map.get(status).add(task.getProcessInstanceId());
                processCoding.setStatus(status);
                processCoding.setOvertimeStatus(overtimeStatus);
                processCoding.setStartTaskTime(task.getCreateTime());
                list.add(processCoding);
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage(),"赋码时间格式有误");
                log.error(e.getMessage(), "赋码时间格式有误");
            }
        }
        //更新项目码
@@ -123,6 +152,42 @@
        if (!CollectionUtils.isEmpty(list)) processCodingMapper.updateBatch(list);
        log.info("结束赋码");
    }
    //减去节点挂起时长
    private long subNodeHangupTime(Map<String, List<ProcessLog>> hangupLogMap, Task task, long durationTime) {
        List<ProcessLog> processLogs = hangupLogMap.get(task.getId());
        if (!CollectionUtils.isEmpty(processLogs)) {
            long hangupTime = 0;
            //分组分为挂起和取消挂起
            Map<ProcessLogEventTypeEnum, List<ProcessLog>> logEventTypeMap = processLogs.stream()
                    .sorted(Comparator.comparing(ProcessLog::getGmtCreate))
                    .collect(Collectors.groupingBy(ProcessLog::getEventType));
            List<ProcessLog> cancelHangup = logEventTypeMap.get(CANCEL_HANGUP);
            for (int i = 0; i < cancelHangup.size(); i++) {
                ProcessLog processLog = cancelHangup.get(i);
                hangupTime += processLog.getGmtCreate().getTime() - logEventTypeMap.get(HANGUP).get(i).getGmtCreate().getTime();
            }
            durationTime = durationTime - hangupTime;
        }
        return durationTime;
    }
    private Long getTime(String timeStr) {
        Long time = null;
        if (StringUtils.isNotBlank(timeStr)) {
            String[] timeArr = timeStr.split("-");
            // 解析天数和小时数
            int days = Integer.parseInt(timeArr[0]);
            int hours = 0;
            if (timeArr.length > 1) {
                hours = Integer.parseInt(timeArr[1]);
            }
            time = (days * 24L + hours) * 3600L;
//            //分-秒
//            time= (days * 60L) + hours;
        }
        return time;
    }
    private Map<String, Date> getStartTaskList(List<ProcessCoding> processCodingList) {
@@ -150,10 +215,11 @@
            return;
        }
        List<Long> projectIds = projectProcessMapper.selectList(
                        new QueryWrapper<ProjectProcess>()
                                .in("process_ins_id", processInstanceIds)
                ).stream()
        List<String> projectIds = new LambdaQueryChainWrapper<>(projectProcessMapper)
                .in(ProjectProcess::getProcessInsId, processInstanceIds)
                .eq(ProjectProcess::getProjectType, ProjectProcessTypeEnum.PROJECT)
                .list()
                .stream()
                .map(ProjectProcess::getProjectId)
                .collect(Collectors.toList());