ludc
2023-07-14 36d3d9da36c71e65081e38cf9cfbd5e0ff6bfeed
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vci.ubcs.flow.core.constant.ProcessConstant;
import com.vci.ubcs.flow.core.dto.FlowTaskDTO;
import com.vci.ubcs.flow.core.entity.BladeFlow;
import com.vci.ubcs.flow.core.entity.FlowTaskUser;
import com.vci.ubcs.flow.core.utils.TaskUtil;
import com.vci.ubcs.flow.engine.entity.*;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
import com.vci.ubcs.flow.engine.service.ProcessStageAttrService;
import com.vci.ubcs.flow.engine.service.VICFlowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.engine.*;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springframework.stereotype.Service;
import java.util.*;
 
/**
 * 工作流服务实现类
 *
 * @author Chill
 */
@Slf4j
@Service
@AllArgsConstructor
public class VCIFlowserviceImpl implements VICFlowService {
 
    private final RuntimeService runtimeService;
    private final IdentityService identityService;
    private final RepositoryService repositoryService;
    private final TaskService taskService;
    private final FlowTaskUserService flowTaskUserService;
    private final FlowEngineService flowEngineService;
    private final HistoryService historyService;
    private final ProcessStageAttrService processStageAttrService;
 
    private static String MODELKEY = "modelKey";//前端传过来的模型key
    private static String TASKID = "taskId";//前端传过来的模型key
    private static String PROCESSINSTANCEID = "processInstanceId";//前端传过来的模型key
    @Override
    public R<BladeFlow> startProcess(FlowTaskDTO flowTaskUserC){
        Map<String, Object> kvv = flowTaskUserC.getVariables();
 
        String modelKey = kvv.get(MODELKEY).toString();
 
        Kv kv = Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName());
 
        // 设置流程启动用户
        identityService.setAuthenticatedUserId(TaskUtil.getTaskUser());
 
        // 开启流程
        //查询最新的流程部署id
        ProcessDefinition latesDefinition = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(modelKey).singleResult();
        String processDefinitionId = latesDefinition.getId();
 
        //查询每一步审核人
        List<FlowTaskUser> taskUsers = flowTaskUserC.getFlowTaskUsers();
//        Set<String> taskIdSet = new HashSet<>();
        for (FlowTaskUser taskUser:taskUsers){
            kv.put(taskUser.getTaskId(),TaskUtil.getTaskUser(taskUser.getUserId()));
//            taskIdSet.add(taskUser.getTaskId());
        }
 
        //对比配置的审核人员和流程中节点是否一致,可能存在流程节点变更了,多了或者少了节点,但是配置审核人员的节点没有变
//        List<Map<String,String>> processTasks = flowEngineService.getNodeByFlowableKey(modelKey);
//        for (Map<String,String> mi:processTasks){
//            String taskId = mi.get(flowEngineService.getTaskIdString());
//            if(!taskIdSet.contains(taskId)){
//                throw new ServiceException("流程已重新部署,节点已改变,请设置审核人员!");
//            }
//        }
//        if(taskIdSet.size()!=processTasks.size()){
//            throw new ServiceException("流程已重新部署,节点已改变,请设置审核人员!");
//        }
 
        //流程中文件、变量等
        if(kvv!=null&&!kvv.isEmpty()){
            kv.putAll(kvv);
        }
 
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, modelKey, kv);
        // 组装流程通用类
        BladeFlow flow = new BladeFlow();
        flow.setProcessInstanceId(processInstance.getId());
 
//        //设置下一步审核人
//        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active().singleResult();
//        String taskId = task.getTaskDefinitionKey();
//        String assignee = null;
//        for (FlowTaskUser taskUser:taskUsers) {
//            if(taskId.equals(taskUser.getTaskId())){
//                assignee = taskUser.getUserId();
//            }
//        }
//        if(StringUtils.isEmpty(assignee)){
//            throw new ServiceException(taskId+"没有配置审核人!");
//        }
//        taskService.setAssignee(task.getId(),assignee);
        return R.data(flow);
    }
 
    public static String NODE_NOW = "now";
    public static String NODE_NEXT = "next";
    /**
     * 获取任务节点
     *
     * @param node   查询节点选择
     * @param processInstanceId 流程实例id
     */
    public FlowTaskDTO nextFlowNode(String node, String processInstanceId) {
        FlowTaskDTO flowTaskDTO = new FlowTaskDTO();
        List<FlowTaskDTO> taskList = new ArrayList<>();//节点按钮
        flowTaskDTO.setToTasks(taskList);
 
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
        ExecutionEntity ee = (ExecutionEntity) runtimeService.createExecutionQuery()
            .executionId(task.getExecutionId()).singleResult();
        // 当前审批节点
        String crruentActivityId = ee.getActivityId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(crruentActivityId);
 
        //这个实例的所有节点
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        Map<String, Object> processVariables = processInstance.getProcessVariables();//所有参数
        flowTaskDTO.setVariables(processVariables);
 
        String modelKey = processInstance.getProcessDefinitionKey();
        List<FlowTaskDTO> mis = flowEngineService.getNodeByFlowableKey(modelKey);
 
        // 输出连线
        List<SequenceFlow> outFlows = flowNode.getOutgoingFlows();
        for (SequenceFlow sequenceFlow : outFlows) {
            //当前审批节点
            if (NODE_NOW.equals(node)) {
                FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
                System.out.println("当前节点: id=" + sourceFlowElement.getId() + ",name=" + sourceFlowElement.getName());
            } else if (NODE_NEXT.equals(node)) {
                // 下一个审批节点
                FlowElement targetFlow = sequenceFlow.getTargetFlowElement();
                if (targetFlow instanceof UserTask) {
                    FlowTaskDTO flowTaskUserCi = new FlowTaskDTO();
                    //flowTaskUserCi.setConditionKey(null);
                    //flowTaskUserCi.setConditionValue(null);
                    flowTaskUserCi.setToName("同意");
                    flowTaskUserCi.setToTaskId(targetFlow.getId());
                    flowTaskUserCi.setToTaskName(targetFlow.getName());
                    taskList.add(flowTaskUserCi);
                }
 
                //结束
                if (targetFlow instanceof EndEvent) {
                    FlowTaskDTO flowTaskUserCi = new FlowTaskDTO();
                    //flowTaskUserCi.setConditionKey(null);
                    //flowTaskUserCi.setConditionValue(null);
                    flowTaskUserCi.setToName("同意");
                    flowTaskUserCi.setToTaskId(targetFlow.getId());
                    flowTaskUserCi.setToTaskName(targetFlow.getName());
                    taskList.add(flowTaskUserCi);
                }
                // 如果下个审批节点为排他网关
                if (targetFlow instanceof ExclusiveGateway) {
 
                    ExclusiveGateway exclusiveGateway = (ExclusiveGateway) targetFlow;
                    List<SequenceFlow> exclusiveGatewayOutgoingFlows = exclusiveGateway.getOutgoingFlows();
                    for (SequenceFlow nexti:exclusiveGatewayOutgoingFlows){
                        String conditionExpression = nexti.getConditionExpression();//condition
                        String taskId = nexti.getTargetRef();//taskId
                        String name = nexti.getName();//toName,驳回、同意
 
                        for (FlowTaskDTO flowTaskUserCi:mis){
                            if(taskId.equals(flowTaskUserCi.getTaskId())){
                                flowTaskUserCi.setCondition(conditionExpression);
                                if(conditionExpression.contains("=")||conditionExpression.contains("<")||conditionExpression.contains(">")) {
                                    conditionExpression = conditionExpression.replace("${","").replace("}","").replaceAll("\"","");
                                    String[] conditionExpressionStr = conditionExpression.split("==");
                                    if(conditionExpression.contains("<")){
                                        conditionExpressionStr = conditionExpression.split("<");
                                    }else if(conditionExpression.contains("<=")){
                                        conditionExpressionStr = conditionExpression.split("<=");
                                    }else if(conditionExpression.contains(">")){
                                        conditionExpressionStr = conditionExpression.split(">");
                                    }else if(conditionExpression.contains(">=")){
                                        conditionExpressionStr = conditionExpression.split(">=");
                                    }
                                    flowTaskUserCi.setConditionKey(conditionExpressionStr.length>0?conditionExpressionStr[0]:null);
                                    flowTaskUserCi.setConditionValue(conditionExpressionStr.length>1?conditionExpressionStr[1]:null);
                                }
                                flowTaskUserCi.setToName(name);
                                flowTaskUserCi.setToTaskId(taskId);
                                flowTaskUserCi.setToTaskName(flowTaskUserCi.getTaskName());
                                taskList.add(flowTaskUserCi);
                            }
                        }
                    }
                }
            }
        }
 
        //流程常量
        Map<String,Object> variables = runtimeService.getVariables(processInstanceId);
        if(!variables.isEmpty()){
            flowTaskDTO.setVariables(variables);
        }
 
 
        //放入流程阶段、流程modelkey
        variables.put(TASKID,crruentActivityId);
        variables.put(PROCESSINSTANCEID,processInstanceId);
        return flowTaskDTO;
    }
}