fuliqi
2025-01-21 ae255b29c1ea01b2668c4e58d9d473f3c3702e1c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package com.ycl.task;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.ycl.domain.entity.ProcessCoding;
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.ProjectInfoMapper;
import com.ycl.mapper.ProjectProcessMapper;
import com.ycl.service.ProcessCodingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskInfo;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
 
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
 
import static com.ycl.common.constant.ProcessOverTimeConstants.*;
 
@Slf4j
@Component("flowableTask")
public class FlowableTask extends FlowServiceFactory {
    @Autowired
    private ProjectProcessMapper projectProcessMapper;
    @Autowired
    private ProjectInfoMapper projectInfoMapper;
    @Autowired
    private ProcessCodingMapper processCodingMapper;
 
    /**
     * 赋码任务
     * 两个逻辑 改项目码、改节点颜色
     */
    public void expireTask() {
        log.info("开始赋码");
        //当前正在运行的所有任务节点
        List<Task> taskList = taskService.createTaskQuery().list();
        if (CollectionUtils.isEmpty(taskList)) return;
        List<String> taskIds = taskList.stream().map(TaskInfo::getId).collect(Collectors.toList());
        //需要监控的赋码任务
        List<ProcessCoding> processCodingList = processCodingMapper.selectList(new QueryWrapper<ProcessCoding>().in("task_id", taskIds));
        Map<String, ProcessCoding> taskMap = new HashMap<>();
        Map<String, Date> startTaskMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(processCodingList)) {
            //key为taskId value为本体对象
            taskMap = processCodingList.stream().collect(Collectors.toMap(ProcessCoding::getTaskId, Function.identity()));
            //拿到开始计时的节点集合 key:taskId value:开始时间
            startTaskMap = getStartTaskList(processCodingList);
        }
        //提前准备接收数据的map key:流程实例id value:需要改变的颜色
        Map<String, List<String>> map = new HashMap<>();
        List<ProcessCoding> list = new ArrayList<>();
        map.put(GREEN, new ArrayList<>());
        map.put(RED, new ArrayList<>());
        map.put(YELLOW, new ArrayList<>());
        Date now = new Date();
        //遍历所有代办的节点
        for (Task task : taskList) {
            String taskId = task.getId();
            ProcessCoding processCoding = taskMap.get(taskId);
            if (processCoding == null) {
                //不需要监控的任务节点直接改为绿色
                List<String> processInsIds = map.get(GREEN);
                processInsIds.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;
                }
                if (startTime == null) continue;
                long durationDay = (now.getTime() - startTime.getTime()) / 1000;
                String status = GREEN; // 默认状态为绿色
                if (redTime != null && redTime !=0 && durationDay >= redTime) {
                    status = RED; // 如果超过红色时间阈值,则状态为红色
                } else if (yellowTime != null && yellowTime !=0 && durationDay >= yellowTime) {
                    status = YELLOW; // 否则,如果超过黄色时间阈值,则状态为黄色
                }
                List<String> processInsIds = map.get(status);
                processInsIds.add(task.getProcessInstanceId());
                processCoding.setStatus(status);
                list.add(processCoding);
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage(),"赋码时间格式有误");
            }
        }
        //更新项目码
        map.forEach((key, value) -> updateProjectCoding(value, key));
        //更新节点状态 自定义的mybatis方法
        if (!CollectionUtils.isEmpty(list)) processCodingMapper.updateBatch(list);
 
        log.info("结束赋码");
    }
 
    private Map<String, Date> getStartTaskList(List<ProcessCoding> processCodingList) {
        //查出任务计时起始节点集合
        List<String> startTaskIds = processCodingList.stream().map(ProcessCoding::getStartTaskId).collect(Collectors.toList());
        //查出起始计时节点数据
        Map<String, Date> startDateMap = new HashMap<>();
        List<HistoricTaskInstance> hisStartTasks = historyService.createHistoricTaskInstanceQuery().taskIds(startTaskIds).list();
        if (!CollectionUtils.isEmpty(hisStartTasks)) {
            hisStartTasks.forEach(hisTask -> {
                startDateMap.put(hisTask.getId(), hisTask.getStartTime());
            });
        }
        return startDateMap;
    }
 
    /**
     * 赋码
     *
     * @param processInstanceIds 流程实例ID列表
     * @param coding             赋码值
     */
    private void updateProjectCoding(List<String> processInstanceIds, String coding) {
        if (CollectionUtils.isEmpty(processInstanceIds)) {
            return;
        }
 
        List<Long> projectIds = projectProcessMapper.selectList(
                        new QueryWrapper<ProjectProcess>()
                                .in("process_ins_id", processInstanceIds)
                ).stream()
                .map(ProjectProcess::getProjectId)
                .collect(Collectors.toList());
 
        if (!CollectionUtils.isEmpty(projectIds)) {
            new LambdaUpdateChainWrapper<>(projectInfoMapper)
                    .in(ProjectInfo::getId, projectIds)
                    .set(ProjectInfo::getCoding, coding)
                    .update();
        }
    }
}