fuliqi
2025-02-10 7ffa0f92413da168a73394b02e06b760778da05c
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
168
169
170
171
172
173
174
175
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 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;
                String status = GREEN; // 默认状态为绿色
                if (redTime != null && redTime !=0 && durationDay >= redTime) {
                    status = RED; // 如果超过红色时间阈值,则状态为红色
                } else if (yellowTime != null && yellowTime !=0 && durationDay >= yellowTime) {
                    status = YELLOW; // 否则,如果超过黄色时间阈值,则状态为黄色
                }
                //处理办理期限
                String overtimeStatus = NORMAL;
                if (overtime != null && overtime !=0 && durationDay >= overtime) {
                    overtimeStatus = OVERTIME; // 如果超过办理期限
                }
                else if (overtime != null && overtime != 0 && durationDay >= (overtime - 12 * 60 * 60)) {
                    overtimeStatus = WILLOVERTIME; // 如果临期(固定超时前12小时为临期)
                }
//                else if (overtime != null && overtime != 0 && durationDay >= (overtime - 60)) {
//                    overtimeStatus = WILLOVERTIME; // 如果临期(固定超时前12小时为临期)
//                }
                List<String> processInsIds = map.get(status);
                processInsIds.add(task.getProcessInstanceId());
 
                processCoding.setStatus(status);
                processCoding.setOvertimeStatus(overtimeStatus);
                list.add(processCoding);
            } catch (Exception e) {
                log.error(e.getMessage(),"赋码时间格式有误");
            }
        }
        //更新项目码
        map.forEach((key, value) -> updateProjectCoding(value, key));
        //更新节点状态 自定义的mybatis方法
        if (!CollectionUtils.isEmpty(list)) processCodingMapper.updateBatch(list);
 
        log.info("结束赋码");
    }
 
    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) {
        //查出任务计时起始节点集合
        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();
        }
    }
}