xiangpei
2024-12-10 5cd0e50ccbc6e10dd4e488d8b4106e82fb676521
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
176
package com.ycl.service.common;
 
import com.alibaba.fastjson2.JSONObject;
import com.ycl.common.constant.ProcessConstants;
import com.ycl.domain.entity.SysForm;
import com.ycl.domain.vo.FormDetailVO;
import com.ycl.flow.FindNextNodeUtil;
import com.ycl.service.ISysFormService;
import lombok.RequiredArgsConstructor;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
 
import java.util.*;
 
/**
 * @author:xp
 * @date:2024/12/4 23:22
 */
@Service
@RequiredArgsConstructor
public class TaskCommonService {
 
    private final RuntimeService runtimeService;
    private final RepositoryService repositoryService;
 
    /**
     * 通过当前节点定义key,获取其上一个节点的定义id,如果前面是并行的会返回多个
     *
     * @param processDefId 流程定义id
     * @param currentNodeDefId
     * @return
     */
    public List<FormDetailVO> getBeforeNodeDefId(String processDefId, String currentNodeDefId, ISysFormService sysFormService, Boolean needInitCurrentForm) {
        // 获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefId)
                .singleResult();
 
        // 获取流程模型
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
        if (bpmnModel == null) {
            throw new RuntimeException("BpmnModel not found for processDefinitionId: " + processDefId);
        }
 
        // 获取流程对象
        Process process = bpmnModel.getProcessById(processDefinition.getKey());
        if (process == null) {
            throw new RuntimeException("Process not found for processDefinitionId: " + processDefId);
        }
 
        // 遍历流程元素,找到对应的任务节点
        Collection<FlowElement> flowElements = process.getFlowElements();
        UserTask currentElement = null;
        for (FlowElement flowElement : flowElements) {
            if (flowElement instanceof UserTask && flowElement.getId().equals(currentNodeDefId)) {
                currentElement = (UserTask) flowElement;
                break;
            }
        }
        if (Objects.isNull(currentElement)) {
            throw new RuntimeException("未找到改任务的流程定义节点");
        }
 
        // 获取当前节点的输入
        List<FormDetailVO> defKeys = new ArrayList<>(2);
        if (StringUtils.hasText(currentElement.getFormKey())) {
            FormDetailVO formDetailVO = new FormDetailVO();
            formDetailVO.setBeforeNodeDefId(currentElement.getId());
            formDetailVO.setBeforeNodeName(currentElement.getName());
            formDetailVO.setCurrent(Boolean.TRUE);
 
            if (needInitCurrentForm) {
                SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(currentElement.getFormKey()));
                if (Objects.isNull(sysForm)) {
                    throw new RuntimeException("该流程绑定的表单不存在或已被删除");
                }
                Map<String, Object> data = new HashMap<>(1);
                data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent()));
 
                formDetailVO.setFormJsonObj(data);
            }
 
            defKeys.add(formDetailVO);
        }
        this.before(currentElement, defKeys);
 
        return defKeys;
    }
 
    /**
     * 递归获取当前节点的前一个任务节点key
     *
     * @param currentElement
     * @param defKeys
     */
    private void before(FlowElement currentElement, List<FormDetailVO> defKeys) {
        if (currentElement instanceof UserTask) {
            UserTask userTask = (UserTask) currentElement;
            if (! CollectionUtils.isEmpty(userTask.getIncomingFlows())) {
                for (SequenceFlow incomingFlow : userTask.getIncomingFlows()) {
                    if (incomingFlow.getSourceFlowElement() instanceof UserTask) {
                        FormDetailVO formDetailVO = new FormDetailVO();
                        formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
                        formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
                        defKeys.add(formDetailVO);
                    } else {
                        before(incomingFlow.getSourceFlowElement(), defKeys);
                    }
                }
            }
        } else if (currentElement instanceof Gateway ){
            Gateway gateway = (Gateway) currentElement;
            if (! CollectionUtils.isEmpty(gateway.getIncomingFlows())) {
                for (SequenceFlow incomingFlow : gateway.getIncomingFlows()) {
                    if (incomingFlow.getSourceFlowElement() instanceof UserTask) {
                        FormDetailVO formDetailVO = new FormDetailVO();
                        formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
                        formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
                        defKeys.add(formDetailVO);
                    } else {
                        before(incomingFlow.getSourceFlowElement(), defKeys);
                    }
                }
            }
        }
//        if (! CollectionUtils.isEmpty(currentElement.getIncomingFlows())) {
//            for (SequenceFlow incomingFlow : currentElement.getIncomingFlows()) {
//                if (! (incomingFlow.getSourceFlowElement() instanceof UserTask)) {
//                    // 不包含开始节点、并行网关、互斥网关,// TODO 还需要排除其它特殊类型
//                    if (! (incomingFlow.getSourceFlowElement() instanceof StartEvent) && ! (incomingFlow.getSourceFlowElement() instanceof ParallelGateway) && ! (incomingFlow.getSourceFlowElement() instanceof ExclusiveGateway)) {
//                        before((UserTask) (incomingFlow.getSourceFlowElement()), defKeys);
//                    }
//                } else {
//                    FormDetailVO formDetailVO = new FormDetailVO();
//                    formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
//                    formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
//                    defKeys.add(formDetailVO);
//                }
//            }
//        }
    }
 
    /**
     * 检查任务节点是否配置了:需要审核  的扩展属性
     *
     * @param extensionElements 扩展列表
     * @return
     */
    public Boolean checkTaskNeedAuditing(List<ExtensionElement> extensionElements) {
        if (CollectionUtils.isEmpty(extensionElements)) {
            return Boolean.FALSE;
        }
        for (ExtensionElement extensionElement : extensionElements) {
            if (CollectionUtils.isEmpty(extensionElement.getAttributes())) { // 如果本身没有属性,则递归child
                return checkTaskNeedAuditing(extensionElement.getChildElements().get("property"));
            } else {
                // 否则先查本身的属性有不有:需要审核 的属性,没有也是递归child
                if (extensionElement.getAttributes().get("name").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_TEXT.equals(attribute.getValue()))
                    && extensionElement.getAttributes().get("value").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_VALUE.equals(attribute.getValue()))
                ) {
                    return Boolean.TRUE;
                } else {
                    return checkTaskNeedAuditing(extensionElement.getChildElements().get("property"));
                }
            }
        }
        return Boolean.FALSE;
    }
 
}