Commit 82e0fcee authored by xiandafu's avatar xiandafu
Browse files

workflow api

parent fb8274e9
package com.ibeetl.starter.workflow.service;
import com.ibeetl.starter.workflow.event.ProcessEndEvent;
import com.ibeetl.starter.workflow.event.ProcessStartEvent;
import com.ibeetl.starter.workflow.event.TaskEndEvent;
import com.ibeetl.starter.workflow.event.TaskOwnerChangeEvent;
import com.ibeetl.starter.workflow.event.TaskStartEvent;
import com.ibeetl.starter.workflow.event.TaslClaimEvent;
/**
* 业务侧接口,业务测的代办中心可以将工作流消息纳入到业务的代办中心
* @author xiandafu
*
*/
public interface WfNotifyService {
public void processStart(ProcessStartEvent startEvent);
public void taskStart(TaskStartEvent startEvent);
public void taskPause(String taskInsId);
public void processPause(String processInsId);
public void taskEnd(TaskEndEvent endEvent);
public void processEnd(ProcessEndEvent endEvent);
public void taskOwnerChanged(TaskOwnerChangeEvent changeEvent);
public void taskClaim(TaslClaimEvent claimEvent);
}
package com.ibeetl.starter.workflow.service;
import java.util.Map;
import org.flowable.task.api.TaskInfo;
import com.ibeetl.starter.workflow.model.SimpleProcessProgress;
import com.ibeetl.starter.workflow.model.WfTaskSpec;
import com.ibeetl.starter.workflow.model.WfUser;
import com.ibeetl.starter.workflow.model.WfUserSpec;
/**
* 业务侧常用接口
* @author xiandafu
*
*/
public interface WfTaskService {
/**
* 启动工作流
* @param procKey
* @param startUser
* @param paras
* @return 第一个task的id
*/
public String start(String procKey, WfUser startUser,Map paras);
/**
* 提交任务, 并保存意见
* @param taskId 任务ID
* @param procInsId 流程实例ID,如果为空,则不保存任务提交意见
* @param comment 任务提交意见的内容
* @param title 流程标题,显示在待办任务标题
* @param vars 任务变量
*/
public void complete(String taskInsId, WfUser acUser,String comment, String title, String buttonCode,WfUser[] targetWfUsers,Map<String, Object> processVars, Map<String, Object> parameters);
/**
* 同上,简洁版的完成,用于单元测试,
* @param taskInsId
* @param acUser
* @param buttonCode
* @param targetAcUser
*/
public void complete(String taskInsId, WfUser wfUser, String buttonCode, WfUser targetWfUser);
/**
* 签收任务,调用签收前,业务侧应该负责检测此用户是否还具备此角色以及部门
* @param taskId 任务ID
* @param userId 签收用户ID(用户登录名)
*/
public boolean claim(WfUser user,String taskInsId);
/**
* 获取某个环节的描述信息,用于业务侧暂时和选人,processKey和processInsId二选一提供
* @param processKey
* @param processInsId
* @param taskId
* @return
*/
public WfTaskSpec getTaskSpec(String processKey,String processInsId,String taskId) ;
/**
* 获取某个环节期望的用户类型
* @param processKey
* @param taskId
* @return
*/
public WfUserSpec getTaskUserDefine(String processKey,String processInsId,String taskId);
/**
* 获取历史执行人,用于选人策略.环节会被多次执行,此获取最新的一次
* @param procInsId
* @param taskId
* @return
*/
public WfUser getHistoryWfUser(String procInsId,String taskKey);
/**
* 获取流程发起人
* @param procInsId
* @return
*/
public WfUser getHistoryProcessOwnerWfUser(String procInsId);
/**
* 委派任务
* @param taskId 任务ID
* @param userId 被委派人
*/
public void delegateTask(String taskInsId, WfUser wfUsers,String comment);
/**
* 撤回流程 ,在用户还未claim情况下可以撤回
* @param taskInsId 当前任务ID
*
*/
public boolean callBackTask(String taskInsId);
/**
* 撤销流程,需要管理人员调用。此删除并没有备份,物理删除了
* @param taskId 任务ID
* @param deleteReason 删除原因
* @param status 结束状态,1 正常结束 2 流程删除
*/
public void processEnd(String procInsId, String deleteReason,Integer status);
/**
* 流程简单的进展
* @param procInsId
* @return
*/
public SimpleProcessProgress getSimpleProgress(String processInsId);
/**
* 重新指定流程执行人
* @param task
* @param assignee
* @param title
*/
public void setTaskAssignee(TaskInfo task,WfUser assignee,String title );
/**
* 判断流程是否执行完毕
* @param taskInsId
* @return
*/
public boolean isProcessCompleted(String taskInsId);
}
package com.ibeetl.starter.workflow.service;
import java.util.Map;
import com.ibeetl.starter.workflow.model.WfUser;
/**
* 管理员接口,用于管理流程,以及实现业务上的任性
* @author xiandafu
*
*/
public interface WfWorkflowManageService {
/**
* 所有运行的流程切换到processId 这个版本
* @param processKey
* @param processInsId
*/
public void overwriteAll(String processKey,String processInsId);
/**
* 切换所有流产到最新版本
* @param processKey
*/
public void overwriteAll(String processKey);
/**
* 多实例节点(子流程)增加一个新的参数人,也适合subProcess
* @param refTaskInsId 参考的代办,建立并行的另外一个代办
* @param user
* @param title
*/
public void addAssignee(String refTaskInsId,WfUser user,String title);
/**
* 删除多示例节点,也适合subProcess
* @param taskInsId
*/
public void removeAssignee(String taskInsId);
/**
* 删除其他代办,直接设置新的代办为历史上的某个环节 ,如果user为空,则设置历史执行人
*
*/
public boolean reset(String executionId,String refTaskInsId,WfUser user);
/**
* 挂起流程
* @param processDefinitionKey
*/
public void suspendProcessByKey(String processDefinitionKey,boolean includeIns);
/**
* 恢复流程
* @param processDefinitionKey
*/
public void activateProcessByKey(String processDefinitionKey);
/**
* 重新设置流程参数
* @param processInsId
* @param paras
*/
public void setProcessParameters(String processInsId,Map paras);
/**
* 重新设置流程执行人
* @param taskInsId
* @param assignee
* @param title
*/
public void setTaskAssignee(String taskInsId,WfUser assignee,String title);
}
package com.ibeetl.starter.workflow.service.impl;
import java.util.List;
import java.util.Map;
import org.flowable.engine.HistoryService;
import org.flowable.engine.IdentityService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskInfo;
import org.springframework.beans.factory.annotation.Autowired;
import com.ibeetl.starter.workflow.engine.CurrentTaskLocal;
import com.ibeetl.starter.workflow.exception.WfException;
import com.ibeetl.starter.workflow.model.InternalTaskStartInfo;
import com.ibeetl.starter.workflow.model.SimpleProcessProgress;
import com.ibeetl.starter.workflow.model.WfTaskSpec;
import com.ibeetl.starter.workflow.model.WfUser;
import com.ibeetl.starter.workflow.model.WfUserSpec;
import com.ibeetl.starter.workflow.service.WfNotifyService;
import com.ibeetl.starter.workflow.service.WfTaskService;
public class WfTaskServiceImpl implements WfTaskService {
@Autowired
protected TaskService taskService;
@Autowired
protected RuntimeService runtimeService;
@Autowired
protected HistoryService historyService;
@Autowired
protected IdentityService identityService;
@Autowired
protected RepositoryService repositoryService;
@Autowired
private ProcessEngine processEngine;
@Autowired
protected WfNotifyService notifyService;
@Override
public String start(String procKey, WfUser startUser,Map paras) {
identityService.setAuthenticatedUserId(startUser.getUserId());
// 启动流程并返回流程实体
ProcessInstance startProcessInstanceById = runtimeService.startProcessInstanceByKey(procKey);
String procInsId = startProcessInstanceById.getId();
// 完成第一个节点,通常是填报节点
List<Task> tasks = taskService.createTaskQuery().processInstanceId(startProcessInstanceById.getId()).list();
if (tasks.size() != 1) {
throw new WfException("错误流程配置,不允许开始有多个节点 " + procKey);
}
Task firstTask = tasks.get(0);
notifyProcessStart(procKey,procInsId,startUser,paras,firstTask);
return firstTask.getId();
}
private void notifyProcessStart(String processKey,String processInsId,WfUser startUser,Map paras,Task firstTask) {
}
@Override
public void complete(String taskInsId, WfUser acUser, String comment, String title, String buttonCode,
WfUser[] targetAcUsers, Map<String, Object> processVars, Map<String, Object> parameters) {
InternalTaskStartInfo taskStartInfo = new InternalTaskStartInfo();
taskStartInfo.setAssigner(acUser);
taskStartInfo.setButtonCode(buttonCode);
taskStartInfo.setStartTaskInsId(taskInsId);
CurrentTaskLocal.setTaskInfo(taskStartInfo);
Task currentTask = taskService.createTaskQuery().taskId(taskInsId).includeTaskLocalVariables().singleResult();
if (currentTask == null) {
throw new WfException("taskInsId=" + taskInsId + " 已经完成或者此代办不存在");
}
// String procInsId = currentTask.getProcessInstanceId();
// FlowElement taskElement = this.getFlowElement(null, procInsId, currentTask.getTaskDefinitionKey());
// List<AcTaskButton> buttons = this.getButtonList(taskElement.getExtensionElements().get("toolbar").get(0));
// AcTaskButton button = this.findButtonByCode(buttons, buttonCode);
//
// // 设置任务点击的按钮,可以用于后面的gateway(如果有) 走向判断
// Map<String, Object> taskVar = new HashMap<String, Object>();
// taskVar.put("buttonCode", buttonCode);
// if (processVars != null && processVars.size() != 0) {
// runtimeService.setVariablesLocal(procInsId, processVars);
// }
//
// if (parameters != null && parameters.size() != 0) {
// taskService.setVariablesLocal(taskInsId, parameters);
// }
//
// taskService.addComment(taskInsId, procInsId, Constants.TYPE_COMMENT_AGREE, comment);
//
// if (Constants.BUTTON_TYPE_JUMP.equals(button.getType())) {
// // 跳转到任意节点
// this.taskJump(taskInsId, button.getTargetRef(), acUser, targetAcUsers[0], title, comment);
// return;
// } else if (Constants.BUTTON_TYPE_WAIT.equals(button.getType())) {
// // 等待,其他按钮或者外部事件来真正完成
// this.taskWait(taskInsId);
// return;
// } else if (Constants.BUTTON_TYPE_END_PROCESS.equals(button.getType())) {
// // 流程结束
// this.processEnd(taskInsId, comment, DeleteReason.PRAOCESS_CANCEL);
// return;
// } else if (Constants.BUTTON_TYPE_MUTILPLE.equals(button.getType())) {
//
// this.taskMutipleTask(currentTask, targetAcUsers, title);
//
// return;
// } else if (Constants.BUTTON_TYPE_GENERAL.equals(button.getType())) {
// taskGeneral(currentTask, targetAcUsers, title);
// } else if (Constants.BUTTON_TYPE_PARALLEL.equals(button.getType())) {
// // 并行流程
// taskParallel(currentTask, targetAcUsers, title);
//
// } else if (Constants.BUTTON_TYPE_AUTO.equals(button.getType())) {
//
// taskAuto(currentTask);
// } else {
// throw new UnsupportedOperationException("不支持的按钮类型" + button.getType());
// }
}
@Override
public void complete(String taskInsId, WfUser wfUser, String buttonCode, WfUser targetWfUser) {
this.complete(taskInsId, wfUser, "", "你有一个代办", buttonCode, new WfUser[] {targetWfUser}, null, null);
}
@Override
public boolean claim(WfUser user, String taskInsId) {
// TODO Auto-generated method stub
return false;
}
@Override
public WfTaskSpec getTaskSpec(String processKey, String processInsId, String taskId) {
// TODO Auto-generated method stub
return null;
}
@Override
public WfUserSpec getTaskUserDefine(String processKey, String processInsId, String taskId) {
// TODO Auto-generated method stub
return null;
}
@Override
public WfUser getHistoryWfUser(String procInsId, String taskKey) {
// TODO Auto-generated method stub
return null;
}
@Override
public WfUser getHistoryProcessOwnerWfUser(String procInsId) {
// TODO Auto-generated method stub
return null;
}
@Override
public void delegateTask(String taskInsId, WfUser wfUsers, String comment) {
// TODO Auto-generated method stub
}
@Override
public boolean callBackTask(String taskInsId) {
// TODO Auto-generated method stub
return false;
}
@Override
public void processEnd(String procInsId, String deleteReason, Integer status) {
// TODO Auto-generated method stub
}
@Override
public SimpleProcessProgress getSimpleProgress(String processInsId) {
// TODO Auto-generated method stub
return null;
}
@Override
public void setTaskAssignee(TaskInfo task, WfUser assignee, String title) {
// TODO Auto-generated method stub
}
@Override
public boolean isProcessCompleted(String taskInsId) {
// TODO Auto-generated method stub
return false;
}
}
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/flowable?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<!-- 最简单流程,建议从此流程入手 -->
<process id="simple" name="简单流程" activiti:processHandler="defaultTaskService">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fillForm" />
<userTask id="fillForm" name="手工填报" >
<extensionElements>
<activiti:user roleId="fill-role" ></activiti:user>
<activiti:toolbar >
<activiti:button type="general" name="submit" displayName="提交" targetRef="agree" strategy="role">
</activiti:button>
</activiti:toolbar>
<activiti:page url=""></activiti:page>
</extensionElements>
</userTask>
<sequenceFlow id="flow2" sourceRef="fillForm" targetRef="agree" />
<userTask id="agree" name="经理复核" >
<extensionElements>
<activiti:user roleId="manager"></activiti:user>
<activiti:toolbar>
<activiti:button type="general" name="agree" displayName="同意" targetRef="theEnd"></activiti:button>
<activiti:button type="jump" name="backLast" displayName="退回" targetRef="fillForm" strategy="task_history" enable="${true}">
<para key="taskId" value="fillForm"></para>
</activiti:button>
</activiti:toolbar>
<activiti:page url="" ></activiti:page>
</extensionElements>
</userTask>
<sequenceFlow id="flow3" sourceRef="agree" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
......@@ -13,6 +13,7 @@
<module>admin-core</module>
<module>admin-console</module>
<module>admin-cloud</module>
<module>admin-workflow</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment