|
|
@@ -0,0 +1,381 @@
|
|
|
+package com.ruoyi.flowable.service.impl;
|
|
|
+
|
|
|
+
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
+import com.ruoyi.flowable.factory.FlowServiceFactory;
|
|
|
+import com.ruoyi.flowable.service.IFlowService;
|
|
|
+import org.flowable.engine.*;
|
|
|
+import org.flowable.engine.form.FormProperty;
|
|
|
+import org.flowable.engine.impl.form.StartFormDataImpl;
|
|
|
+import org.flowable.engine.impl.form.TaskFormDataImpl;
|
|
|
+import org.flowable.engine.runtime.ProcessInstance;
|
|
|
+import org.flowable.task.api.Task;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class FlowServiceImpl extends FlowServiceFactory implements IFlowService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TaskService taskService;
|
|
|
+ @Autowired
|
|
|
+ private HistoryService historyService;
|
|
|
+ @Autowired
|
|
|
+ private RuntimeService runtimeService;
|
|
|
+ @Autowired
|
|
|
+ private FormService formService;
|
|
|
+ @Autowired
|
|
|
+ private IdentityService identityService;
|
|
|
+ @Autowired
|
|
|
+ private RepositoryService repositoryService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据任务Id获取流程实例信息
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ProcessInstance getProcessInstance(String taskId){
|
|
|
+
|
|
|
+ ProcessInstance pInstan = null;
|
|
|
+ try{
|
|
|
+ Task task = taskService.createTaskQuery().taskId(taskId).active().singleResult();
|
|
|
+
|
|
|
+ if(task != null){
|
|
|
+ String processInstanceId = task.getProcessInstanceId();
|
|
|
+
|
|
|
+ pInstan = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
|
|
|
+ }
|
|
|
+ }catch(Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return pInstan;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据任务对象获取流程实例信息
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ProcessInstance getProcessInstance(Task task){
|
|
|
+
|
|
|
+ ProcessInstance pInstan = null;
|
|
|
+
|
|
|
+ try{
|
|
|
+ if(task != null){
|
|
|
+ String processInstanceId = task.getProcessInstanceId();
|
|
|
+
|
|
|
+ pInstan = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
|
|
|
+ }
|
|
|
+
|
|
|
+ }catch(Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return pInstan;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取节点的formkey值
|
|
|
+ */
|
|
|
+ /*@Override
|
|
|
+ public String getFormKey(String pInstId, String taskId, String opType){
|
|
|
+
|
|
|
+ String formKey = "";
|
|
|
+
|
|
|
+ if(StringUtils.isNotBlank(pInstId)) {
|
|
|
+ if(StringUtils.isNotBlank(taskId)){
|
|
|
+ formKey = formService.getTaskFormKey(pInstId, taskId);
|
|
|
+ }
|
|
|
+ // 如果指定的任务没有设置 formkey, 则取表单开始节点设置的 formkey
|
|
|
+ if(StringUtils.isBlank(formKey) || "detail".equals(opType)){
|
|
|
+ formKey = formService.getStartFormKey(pInstId);
|
|
|
+
|
|
|
+ if(StringUtils.isNotBlank(formKey)){
|
|
|
+
|
|
|
+ *//**
|
|
|
+ * 以流程开始节点为基准, 根据opType参数和固定的规则来构建 表单请求路径
|
|
|
+ *//*
|
|
|
+
|
|
|
+ // 申请表单 -- 因为开始节点设置的 formkey 就是申请表单,所以暂时不需要处理
|
|
|
+ if(AcOperateTypeEnum.CREATE.eq(opType)){
|
|
|
+
|
|
|
+ }else if(AcOperateTypeEnum.DETAIL.eq(opType)){ // 表单详情
|
|
|
+ int index = formKey.lastIndexOf("/");
|
|
|
+ formKey = formKey.substring(0, index) + "/detail";
|
|
|
+ }else if(AcOperateTypeEnum.AUDIT.eq(opType)){ // 表单审核
|
|
|
+ int index = formKey.lastIndexOf("/");
|
|
|
+ formKey = formKey.substring(0, index) + "/audit";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return formKey;
|
|
|
+ }*/
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取表单信息, 如果 taskId 不为空则获取指定taskId的表单,否则就根据pDefId获取流程开始节点定义的表单
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getFormProperties(String pDefId, String taskId){
|
|
|
+
|
|
|
+ Map<String, Object> rs = new HashMap<>();
|
|
|
+
|
|
|
+ try{
|
|
|
+
|
|
|
+ List<FormProperty> formProperties = null;
|
|
|
+
|
|
|
+ if(StringUtils.isNotBlank(taskId)) {
|
|
|
+ TaskFormDataImpl taskFormData = (TaskFormDataImpl) formService.getTaskFormData(taskId);
|
|
|
+ // 设置task为null,否则输出json的时候会报错
|
|
|
+ taskFormData.setTask(null);
|
|
|
+
|
|
|
+ formProperties = taskFormData.getFormProperties();
|
|
|
+
|
|
|
+ rs.put("form", taskFormData);
|
|
|
+
|
|
|
+ } else if(StringUtils.isNotBlank(pDefId)){
|
|
|
+ StartFormDataImpl startFormData = (StartFormDataImpl) formService.getStartFormData(pDefId);
|
|
|
+ startFormData.setProcessDefinition(null);
|
|
|
+
|
|
|
+ formProperties = startFormData.getFormProperties();
|
|
|
+
|
|
|
+ rs.put("form", startFormData);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(formProperties != null){
|
|
|
+ for (FormProperty formProperty : formProperties) {
|
|
|
+ Map<String, String> values = (Map<String, String>) formProperty.getType().getInformation("values");
|
|
|
+
|
|
|
+ if (values != null) {
|
|
|
+ for (Map.Entry<String, String> enumEntry : values.entrySet()) {
|
|
|
+ }
|
|
|
+ rs.put(formProperty.getId(), values);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }catch(Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return rs;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 给指定的表单map赋值,并返回 表单form的字符串表示形式
|
|
|
+ */
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getFormProperties(Map<String, Object> fpMap, Map<String, String[]> mapParams) {
|
|
|
+
|
|
|
+ String fpMapStr = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ if(fpMap != null && mapParams != null){
|
|
|
+
|
|
|
+ ObjectMapper objMapper = new ObjectMapper();
|
|
|
+ fpMapStr = objMapper.writeValueAsString(fpMap);
|
|
|
+
|
|
|
+ Map<String, Object> fpMapNew = objMapper.readValue(fpMapStr, Map.class);
|
|
|
+
|
|
|
+ Object oFormMap = fpMapNew.get("form");
|
|
|
+ if(oFormMap != null){
|
|
|
+
|
|
|
+ Map<String, Object> formMap = (Map<String, Object>)oFormMap;
|
|
|
+ Object oFormProperties = formMap.get("formProperties");
|
|
|
+ if(oFormProperties != null){
|
|
|
+ List<Map<String, Object>> lstFpMap = (List<Map<String, Object>>)oFormProperties;
|
|
|
+
|
|
|
+ for(Map<String, Object> fp : lstFpMap){
|
|
|
+ String id = "fp_" + fp.get("id").toString();
|
|
|
+
|
|
|
+ if(mapParams.containsKey(id)){
|
|
|
+ fp.put("value", mapParams.get(id)[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return objMapper.writeValueAsString(fpMapNew);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return fpMapStr;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> taskComplete(String taskId, boolean isOk, Map<String, Object> map, String loginId) throws Exception {
|
|
|
+
|
|
|
+ Map<String, Object> rs = new HashMap<String, Object>();
|
|
|
+
|
|
|
+ rs.put("status", false);
|
|
|
+
|
|
|
+ Map<String, Object> formProperties = new HashMap<String, Object>();
|
|
|
+ TaskFormDataImpl taskFormData = (TaskFormDataImpl) formService.getTaskFormData(taskId);
|
|
|
+
|
|
|
+ if (taskFormData != null) {
|
|
|
+ // 设置task为null,否则输出json的时候会报错
|
|
|
+ taskFormData.setTask(null);
|
|
|
+
|
|
|
+ List<FormProperty> lstFormProperties = taskFormData.getFormProperties();
|
|
|
+ if (lstFormProperties != null) {
|
|
|
+ for (FormProperty formProperty : lstFormProperties) {
|
|
|
+ if (!formProperty.isWritable()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ formProperties.put(formProperty.getId(), formProperty.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Map.Entry<String, Object> mm : map.entrySet()) {
|
|
|
+ formProperties.put(mm.getKey(), mm.getValue());
|
|
|
+ }
|
|
|
+ // 从request中读取参数然后转换
|
|
|
+ formProperties.put("isOk", String.valueOf(isOk));
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 设置审批人,以及提交审批信息
|
|
|
+ identityService.setAuthenticatedUserId(loginId);
|
|
|
+ taskService.complete(taskId, formProperties);
|
|
|
+// formService.submitTaskFormData(taskId, formProperties);
|
|
|
+ rs.put("status", true);
|
|
|
+ // String msg = isOk ? "审核完成,同意成功!" : "审核完成,驳回成功!";
|
|
|
+ String msg = "审核完成!";
|
|
|
+ rs.put("msg", msg);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ rs.put("status", false);
|
|
|
+ rs.put("msg", "审核失败!");
|
|
|
+ } finally {
|
|
|
+ identityService.setAuthenticatedUserId(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ return rs;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @Description (跳转任意目标节点)
|
|
|
+ * @author liuwei
|
|
|
+ * @Date 2021年11月3日上午10:23:00
|
|
|
+ * @version 1.0.0
|
|
|
+ * @param map
|
|
|
+ * taskId,destTaskKey,rejectMessage,outcome
|
|
|
+ */
|
|
|
+ /*@Override
|
|
|
+ public void skipStipulationTask(Map<String, Object> map) {
|
|
|
+ String taskId = (String) map.get("taskId");
|
|
|
+ // 目标任务key
|
|
|
+ String destTaskKey = (String) map.get("destTaskKey");
|
|
|
+ //审批消息
|
|
|
+ String rejectMessage = (String) map.get("rejectMessage");
|
|
|
+ //流程线
|
|
|
+ String outcome = (String) map.get("outcome");
|
|
|
+ //业务的用户ID
|
|
|
+ String uid = (String) map.get("uid");
|
|
|
+ //审批消息
|
|
|
+ String message = (String) map.get("message");
|
|
|
+ // 使用任务ID,获取任务信息
|
|
|
+ Task taskEntity = taskService.createTaskQuery().taskId(taskId).singleResult();
|
|
|
+ // 获得当前任务的流程实例ID
|
|
|
+ String processInstanceId = taskEntity.getProcessInstanceId();
|
|
|
+
|
|
|
+ // 获得当前任务的流程定义ID
|
|
|
+ String processDefinitionId = taskEntity.getProcessDefinitionId();
|
|
|
+ // 当前任务key
|
|
|
+ String currtaskDefKey = taskEntity.getTaskDefinitionKey();
|
|
|
+
|
|
|
+ // 获得当前活动节点和驳回的目标节点"draft"
|
|
|
+ ActivityImpl currActiviti = null;// 当前活动节点
|
|
|
+ ActivityImpl destActiviti = null;// 驳回目标节点
|
|
|
+
|
|
|
+ currActiviti = getActivityImpl(currtaskDefKey, processDefinitionId);
|
|
|
+ destActiviti = getActivityImpl(destTaskKey, processDefinitionId);
|
|
|
+
|
|
|
+ // 保存当前活动节点的流程流出参数
|
|
|
+
|
|
|
+ List<PvmTransition> hisPvmTransitionList = new ArrayList<PvmTransition>(0);
|
|
|
+
|
|
|
+ for (PvmTransition pvmTransition : currActiviti.getOutgoingTransitions()) {
|
|
|
+ hisPvmTransitionList.add(pvmTransition);
|
|
|
+ }
|
|
|
+ // 清空当前活动节点的所有流出项
|
|
|
+
|
|
|
+ currActiviti.getOutgoingTransitions().clear();
|
|
|
+ // 为当前节点动态创建新的流出项
|
|
|
+
|
|
|
+ TransitionImpl newTransitionImpl = currActiviti.createOutgoingTransition();
|
|
|
+ // 为当前活动节点新的流出项指定为目标流程节点
|
|
|
+ newTransitionImpl.setDestination(destActiviti);
|
|
|
+ // 保存驳回意见
|
|
|
+ taskEntity.setDescription(rejectMessage);// 设置驳回意见
|
|
|
+ taskService.saveTask(taskEntity);
|
|
|
+
|
|
|
+ *//**
|
|
|
+ * 注意:添加批注的时候,由于Activiti底层代码是使用: String userId =
|
|
|
+ * Authentication.getAuthenticatedUserId(); CommentEntity comment = new
|
|
|
+ * CommentEntity(); comment.setUserId(userId);
|
|
|
+ * 所有需要从Session中获取当前登录人,作为该任务的办理人(审核人),对应act_hi_comment表中的User_ID的字段,
|
|
|
+ * 不添加审核人,该字段为null
|
|
|
+ * 所以要求,添加配置执行使用Authentication.setAuthenticatedUserId();添加当前任务的审核人
|
|
|
+ *//*
|
|
|
+ Authentication.setAuthenticatedUserId(uid);
|
|
|
+ taskService.addComment(taskId, processInstanceId, message);
|
|
|
+
|
|
|
+ // 设定驳回标志
|
|
|
+ Map<String, Object> variables = new HashMap<String, Object>(0);
|
|
|
+ variables.put("outcome", outcome);
|
|
|
+ // 执行当前任务驳回到目标任务draft
|
|
|
+ taskService.complete(taskEntity.getId(), variables);
|
|
|
+ // 清除目标节点的新流入项
|
|
|
+ destActiviti.getIncomingTransitions().remove(newTransitionImpl);
|
|
|
+ // 清除原活动节点的临时流程项
|
|
|
+ currActiviti.getOutgoingTransitions().clear();
|
|
|
+ // 还原原活动节点流出项参数
|
|
|
+ currActiviti.getOutgoingTransitions().addAll(hisPvmTransitionList);
|
|
|
+ }*/
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @Description (通过任务key,获取对应的节点信息)
|
|
|
+ * @author liuwei
|
|
|
+ * @Date 2021年11月3日下午1:53:29
|
|
|
+ * @version 1.0.0
|
|
|
+ * @param destTaskKey
|
|
|
+ * @param processDefinitionId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ /*public ActivityImpl getActivityImpl(String destTaskKey, String processDefinitionId) {
|
|
|
+ // 获得当前流程的定义模型
|
|
|
+ ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
|
|
|
+ .getDeployedProcessDefinition(processDefinitionId);
|
|
|
+
|
|
|
+ // 获得当前流程定义模型的所有任务节点
|
|
|
+
|
|
|
+ List<ActivityImpl> activitilist = processDefinition.getActivities();
|
|
|
+ // 获得当前活动节点和驳回的目标节点"draft"
|
|
|
+ ActivityImpl descActiviti = null;// 当前活动节点
|
|
|
+
|
|
|
+ for (ActivityImpl activityImpl : activitilist) {
|
|
|
+ // 获取节点对应的key
|
|
|
+ String taskKey = activityImpl.getId();
|
|
|
+ // 确定当前活动activiti节点
|
|
|
+ if (destTaskKey.equals(taskKey)) {
|
|
|
+ descActiviti = activityImpl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return descActiviti;
|
|
|
+ }*/
|
|
|
+}
|