diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/pom.xml b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/pom.xml
index 24006dd32..f1b0fd14f 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/pom.xml
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/pom.xml
@@ -142,5 +142,10 @@
${project.version}
test
+
+ org.hswebframework.web
+ hsweb-tests
+ 3.0-SNAPSHOT
+
\ No newline at end of file
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/FlowableAutoConfiguration.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/FlowableAutoConfiguration.java
index 9edc20720..0fb8a6c36 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/FlowableAutoConfiguration.java
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/FlowableAutoConfiguration.java
@@ -39,17 +39,8 @@ public class FlowableAutoConfiguration {
configuration.setCustomSessionFactories(sessionFactories);
}
};
-
-// ProcessEngineConfiguration processEngineConfiguration = new StandaloneProcessEngineConfiguration()
-// .setAsyncExecutorActivate(false)
-// .setJobExecutorActivate(false)
-// .setActivityFontName("宋体")
-// .setLabelFontName("宋体")
-// .setAnnotationFontName("宋体");
-// return processEngineConfiguration;
}
-
@ConditionalOnBean(UserService.class)
@Configuration
public static class CustomEntityManagerAutoConfiguration {
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/controller/BpmDeploymentController.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/controller/BpmDeploymentController.java
index a3449dd29..1f9f4a7fb 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/controller/BpmDeploymentController.java
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/controller/BpmDeploymentController.java
@@ -7,7 +7,9 @@ import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
+import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
@@ -19,7 +21,13 @@ import org.hsweb.ezorm.core.param.TermType;
import org.hswebframework.web.commons.entity.PagerResult;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.workflow.flowable.service.BpmActivityService;
+import org.hswebframework.web.workflow.flowable.service.BpmProcessService;
+import org.hswebframework.web.workflow.flowable.service.BpmTaskService;
import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -42,6 +50,16 @@ import java.util.zip.ZipInputStream;
@RequestMapping("/workflow/definition")
public class BpmDeploymentController extends FlowableAbstract {
+ protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Autowired
+ BpmTaskService bpmTaskService;
+
+ @Autowired
+ BpmProcessService bpmProcessService;
+ @Autowired
+ BpmActivityService bpmActivityService;
+
/**
* 流程定义列表
*/
@@ -223,4 +241,49 @@ public class BpmDeploymentController extends FlowableAbstract {
}
return jsonObject;
}
+
+ /**
+ * 查看当前节点流程图
+ * @param processInstanceId
+ * @return 当前节点
+ * window.open('/showImage?processInstanceId=' + processInstanceId, 'newwindow', 'height=500, width=1000, top=100,left=200, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no');
+ *
+ <#if message??>
+
${message!}
+ <#else>
+
}/workflow/document/alldoc/findPic/${procDefId!})
+
+
+ #if>
+
+ */
+ @GetMapping("/showImage/{processInstanceId}")
+ public Object showImage(@PathVariable String processInstanceId){
+ JSONObject jsonObject = new JSONObject();
+ HistoricProcessInstance processInstance = bpmTaskService.selectHisProInst(processInstanceId);
+ if(processInstance!=null){
+ ActivityImpl activity = bpmActivityService.getActivityByProcInstId(processInstance.getProcessDefinitionId(),processInstance.getId());
+ jsonObject.put("activity",activity);
+ jsonObject.put("procDefId",processInstance.getProcessDefinitionId());
+ }else{
+ jsonObject.put("message","获取流程图失败");
+ logger.debug("获取流程节点,processInstanceId:"+processInstanceId);
+ }
+ return jsonObject;
+ }
+
+ @GetMapping("/findPic/{procDefId}")
+ public void findPic(@PathVariable String procDefId,HttpServletResponse response){
+ try{
+ InputStream inputStream = bpmProcessService.findProcessPic(procDefId);
+ byte[] b = new byte[1024];
+ int len = 0;
+ while ((len = inputStream.read(b,0,1024))!=-1){
+ response.getOutputStream().write(b, 0, len);
+ }
+ }catch (Exception e){
+ logger.debug("获取流程图失败,procDefId:"+procDefId);
+ }
+ }
}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/entity/TaskInfo.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/entity/TaskInfo.java
new file mode 100644
index 000000000..003951d82
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/entity/TaskInfo.java
@@ -0,0 +1,126 @@
+package org.hswebframework.web.workflow.flowable.entity;
+
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.task.Task;
+import org.hswebframework.web.commons.entity.SimpleGenericEntity;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @Author wangwei
+ * @Date 2017/8/4.
+ */
+public class TaskInfo extends SimpleGenericEntity {
+
+ public static final String TYPE_TODO = "todo";
+
+ public static final String TYPE_CLAIM = "claim";
+
+ private String name;
+
+ private Date createDate;
+
+ private ProcessDefinition definition;
+
+ private String formId;
+
+ private String dataId;
+
+ private Object mainFormData;
+
+ private String pid;
+
+ private String processInstanceId;
+
+ private String type;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getCreateDate() {
+ return createDate;
+ }
+
+ public void setCreateDate(Date createDate) {
+ this.createDate = createDate;
+ }
+
+ public ProcessDefinition getDefinition() {
+ return definition;
+ }
+
+ public void setDefinition(ProcessDefinition definition) {
+ this.definition = definition;
+ }
+
+ public String getPid() {
+ return pid;
+ }
+
+ public void setPid(String pid) {
+ this.pid = pid;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getProcessInstanceId() {
+ return processInstanceId;
+ }
+
+ public void setProcessInstanceId(String processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
+
+ public TaskInfo initFromProtoType(Task task) {
+ this.setId(task.getId());
+ this.setName(task.getName());
+ this.setCreateDate(task.getCreateTime());
+ this.setProcessInstanceId(task.getProcessInstanceId());
+ this.setPid(task.getParentTaskId());
+ Map var = task.getProcessVariables();
+ this.setFormId((String) var.get("mainFormId"));
+ this.setDataId((String) var.get("mainFormDataId"));
+ return this;
+ }
+
+
+ public static TaskInfo buildFromProtoType(Task task) {
+ return new TaskInfo().initFromProtoType(task);
+ }
+
+ public String getFormId() {
+ return formId;
+ }
+
+ public void setFormId(String formId) {
+ this.formId = formId;
+ }
+
+ public String getDataId() {
+ return dataId;
+ }
+
+ public void setDataId(String dataId) {
+ this.dataId = dataId;
+ }
+
+ public Object getMainFormData() {
+ return mainFormData;
+ }
+
+ public void setMainFormData(Object mainFormData) {
+ this.mainFormData = mainFormData;
+ }
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmActivityService.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmActivityService.java
new file mode 100644
index 000000000..2649771c1
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmActivityService.java
@@ -0,0 +1,59 @@
+package org.hswebframework.web.workflow.flowable.service;
+
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
+
+import java.util.List;
+
+/**
+ * 流程节点操作的接口
+ * @Author wangwei
+ * @Date 2017/8/4.
+ */
+public interface BpmActivityService {
+ /**
+ * 获取指定节点
+ *
+ * @param procDefId 流程定义ID
+ * @return ActivityImpl 指定的节点资源
+ */
+ ActivityImpl getActivityById(String procDefId, String activityId);
+
+ /**
+ * 获取指定节点
+ *
+ * @param procDefKey 流程定义Key
+ * @return ActivityImpl 指定的节点,未指定返回当前节点
+ */
+ ActivityImpl getActivityByKey(String procDefKey, String activityId);
+
+ /**
+ * 获取所有节点
+ *
+ * @param procDefId 流程定义ID
+ * @return List 当前流程的所有节点资源
+ */
+ List getActivitys(String procDefId);
+
+ /**
+ * 获取所有userTask
+ *
+ * @param procDefId 流程定义ID
+ * @return List 当前流程的所有userTask资源
+ */
+ List getUserTasks(String procDefId);
+
+ /**
+ * 获取结束节点
+ * @param procDefId 流程定义ID
+ * @return ActivityImpl 当前流程的结束资源
+ */
+ ActivityImpl getEndActivityImpl(String procDefId);
+
+ /***
+ * 获取当前执行节点
+ * @param procDefId 流程定义ID
+ * @param procInstId 流程实例ID
+ * @return
+ */
+ ActivityImpl getActivityByProcInstId(String procDefId, String procInstId);
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmProcessService.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmProcessService.java
new file mode 100644
index 000000000..0e14ec8fe
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmProcessService.java
@@ -0,0 +1,83 @@
+package org.hswebframework.web.workflow.flowable.service;
+
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.Job;
+import org.activiti.engine.runtime.ProcessInstance;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 流程实例操作相关接口
+ * @Author wangwei
+ * @Date 2017/8/4.
+ */
+public interface BpmProcessService{
+
+ /**
+ * 启动一个流程,并初始化自定义主表单数据
+ *
+ * @param creator_id 流程创建人
+ * @param procDefKey 流程定义key
+ * @param activity 下一环节id
+ * @param next_claim 下一步执行人
+ * @param businessKey 业务数据ID
+ * @param variables 启动参数(流程变量,流程未结束前任意环节都可以使用)
+ * @return 启动后的流程实例
+ * @throws Exception 异常信息
+ */
+ ProcessInstance startProcessInstance(String creator_id, String procDefKey, String activity, String next_claim,
+ String businessKey,
+ Map variables);
+
+ /**
+ * 根据流程图key获取所有运行中流程分页
+ * @param page
+ * @param num
+ * @param procDefKey
+ * @return
+ */
+ List getProcessInstances(int page, int num, String procDefKey);
+
+ /**
+ * 流程实例挂起
+ * @param procInstId 流程实例ID
+ */
+ void closeProcessInstance(String procInstId);
+
+ /**
+ * 流程实例激活
+ * @param procInstId 流程实例ID
+ */
+ void openProcessInstance(String procInstId);
+
+ /**
+ * 根据流程定义id获取流程定义实例
+ * 此方法使用了缓存,返回的{@link org.activiti.engine.repository.ProcessDefinition}实例不为activity默认的实例,而是{@link ProcessDefinitionCache},以保证缓存时正常序列化
+ *
+ * @param procDefId 流程定义id
+ * @return 流程定义实例
+ * @throws Exception 异常信息
+ */
+ ProcessDefinition getProcessDefinition(String procDefId);
+
+ /***
+ * 获取job事件
+ * @param procInstId 执行ID
+ */
+ Job getJob(String procInstId);
+
+ /***
+ * 强制删除job任务,该方法无 api 接口
+ * @param jobId
+ */
+ int deleteJob(String jobId);
+
+ /***
+ * 查看流程图
+ * @param procDefId 流程定义id
+ * @return
+ */
+ InputStream findProcessPic(String procDefId);
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmTaskService.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmTaskService.java
new file mode 100644
index 000000000..90079a5ec
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/BpmTaskService.java
@@ -0,0 +1,137 @@
+package org.hswebframework.web.workflow.flowable.service;
+
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.task.Task;
+import org.hswebframework.web.workflow.flowable.entity.TaskInfo;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 流程任务操作相关接口
+ * @Author wangwei
+ * @Date 2017/8/4.
+ */
+public interface BpmTaskService{
+
+ List selectNowTask(String procInstId);
+
+ Task selectTaskByProcessId(String procInstId);
+
+ Task selectTaskByTaskId(String taskId);
+
+ String selectNowTaskName(String procInstId);
+
+ String selectNowTaskId(String procInstId);
+
+ HistoricProcessInstance selectHisProInst(String procInstId);
+
+ /**
+ * 领取(签收)任务
+ *
+ * @param taskId 任务id
+ * @param userId 用户id
+ * @throws Exception 异常信息
+ */
+ void claim(String taskId, String userId);
+
+
+ /**
+ * 预留等待签收的任务
+ *
+ * @param userId 用户id
+ * @return 任务信息
+ * @throws Exception
+ */
+ List claimList(String userId);
+
+ /**
+ * 已签收待办理的任务
+ *
+ * @param userId 用户id
+ * @return 任务信息
+ * @throws Exception
+ */
+ List todoList(String userId);
+
+ /**
+ * 完成任务(环节)并指定下一环节办理人
+ *
+ * @param taskId 任务id
+ * @param userId 用户id
+ * @param activityId 人为指定下一执行环节(预留)
+ * @param next_claim 人为指定下一步执行人(预留)
+ * @throws Exception 异常信息
+ */
+ void complete(String taskId, String userId, String activityId, String next_claim);
+
+ /**
+ * 流程任意跳转
+ * @param procInstId 流程实例ID
+ * @param activity 流程环节ID
+ * @param next_claim 下一步执行人
+ */
+ void jumpTask(String procInstId, String activity, String next_claim);
+
+ /**
+ * 设置办理人
+ *
+ * @param taskId 当前环节ID
+ * @param userId 用户ID
+ */
+ void setAssignee(String taskId, String userId);
+ /**
+ * 结束流程
+ * @param procInstId 流程实例ID
+ */
+ void endProcess(String procInstId);
+
+ /**
+ * 删除历史环节信息
+ * @param taskId 环节ID
+ */
+ void removeHiTask(String taskId);
+
+ /**
+ * 获取所有任务节点
+ * @param procDefKey 流程定义Key,该参数获取最新流程
+ */
+ Map getUserTasksByProcDefKey(String procDefKey);
+
+ /**
+ * 获取所有任务节点
+ * @param procInstId 流程实例ID,该参数获取当前流程实例对应流程
+ */
+ Map getUserTasksByProcInstId(String procInstId);
+
+ /**
+ * 设置流程变量
+ *
+ * @param taskId 当前环节ID
+ * @param map key-value
+ */
+ void setVariables(String taskId,Map map);
+
+ /**
+ * 删除流程变量
+ *
+ * @param taskId 当前环节ID
+ * @param var2 需要删除的 key
+ */
+ void removeVariables(String taskId,Collection var2);
+
+ /**
+ * 设置任务变量
+ *
+ * @param taskId 当前环节ID
+ */
+ void setVariablesLocal(String taskId, Map map);
+
+ /***
+ * 获取流程变量
+ * @param procInstId 流程实例ID
+ */
+ Map getVariables(String procInstId);
+
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmActivityServiceImp.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmActivityServiceImp.java
new file mode 100644
index 000000000..f37828a36
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmActivityServiceImp.java
@@ -0,0 +1,102 @@
+package org.hswebframework.web.workflow.flowable.service.imp;
+
+import org.activiti.engine.impl.RepositoryServiceImpl;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.hswebframework.web.workflow.flowable.service.BpmActivityService;
+import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author wangwei
+ * @Date 2017/8/7.
+ */
+@Service
+public class BpmActivityServiceImp extends FlowableAbstract implements BpmActivityService {
+
+ /**
+ * 获取指定节点
+ *
+ * @param procDefId 流程定义ID
+ * @return ActivityImpl 指定的节点资源
+ */
+ @Override
+ public ActivityImpl getActivityById(String procDefId, String activityId){
+ return getProcessDefinition(procDefId).findActivity(activityId);
+ }
+
+ @Override
+ public ActivityImpl getActivityByKey(String procDefKey, String activityId) {
+ ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).orderByProcessDefinitionVersion().desc().list().get(0);
+ String procDefId = definition.getId();
+ return getProcessDefinition(procDefId).findActivity(activityId);
+ }
+
+ /**
+ * 获取所有节点
+ *
+ * @param processDefId 流程定义ID
+ * @return List 当前流程的所有节点资源
+ */
+ @Override
+ public List getActivitys(String processDefId){
+ ProcessDefinitionEntity pde = getProcessDefinition(processDefId);
+ return pde.getActivities();
+ }
+
+ /**
+ * 获取所有userTask
+ *
+ * @param procDefId 流程定义ID
+ * @return List 当前流程的所有userTask资源
+ */
+ @Override
+ public List getUserTasks(String procDefId){
+ ProcessDefinitionEntity pde = getProcessDefinition(procDefId);
+ List activityList = new ArrayList<>();
+ for(ActivityImpl activity : pde.getActivities()){
+ if(activity.getProperty("type").equals("userTask"))
+ activityList.add(activity);
+ }
+ return activityList;
+ }
+
+ /**
+ * 获取结束节点
+ * @param procDefId 流程定义ID
+ * @return ActivityImpl 当前流程的结束资源
+ */
+ @Override
+ public ActivityImpl getEndActivityImpl(String procDefId){
+ ProcessDefinitionEntity pde = getProcessDefinition(procDefId);
+ for(ActivityImpl activity : pde.getActivities()){
+ if(activity.getProperty("type").equals("endEvent"))
+ return activity;
+ }
+ return null;
+ }
+
+ /**
+ * 获取流程定义
+ *
+ * @param procDefId 流程定义ID
+ * @return 流程定义资源
+ */
+ public ProcessDefinitionEntity getProcessDefinition(String procDefId){
+ return (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(procDefId);
+ }
+
+ @Override
+ public ActivityImpl getActivityByProcInstId(String procDefId, String procInstId) {
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId)
+ .active().singleResult();
+ String activityId = processInstance.getActivityId();
+
+ return getProcessDefinition(procDefId).findActivity(activityId);
+ }
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmProcessServiceImp.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmProcessServiceImp.java
new file mode 100644
index 000000000..90e257484
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmProcessServiceImp.java
@@ -0,0 +1,113 @@
+package org.hswebframework.web.workflow.flowable.service.imp;
+
+import org.activiti.engine.impl.RepositoryServiceImpl;
+import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
+import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.Job;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.runtime.ProcessInstanceQuery;
+import org.activiti.engine.task.Task;
+import org.hswebframework.utils.StringUtils;
+import org.hswebframework.web.workflow.flowable.service.BpmProcessService;
+import org.hswebframework.web.workflow.flowable.service.BpmTaskService;
+import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author wangwei
+ * @Date 2017/8/7.
+ */
+@Service
+public class BpmProcessServiceImp extends FlowableAbstract implements BpmProcessService {
+ protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Resource
+ BpmTaskService bpmTaskService;
+
+ @Override
+ public ProcessInstance startProcessInstance(String creator_id,String procDefKey,String activity,String next_claim,
+ String businessKey,
+ Map variables){
+ logger.debug("start flow :", procDefKey);
+ ProcessInstance processInstance = null;
+ try{
+ // 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
+ identityService.setAuthenticatedUserId(creator_id);
+ logger.debug("流程启动,work_flow_key:{}", procDefKey);
+ logger.debug("表单ID,businessKey:{}",businessKey);
+ logger.debug("流程变量保存,variables:{}",variables);
+ //启动流程,返回流程实例
+ processInstance = runtimeService.startProcessInstanceByKey(procDefKey, businessKey, variables);
+ //获取流程实例ID
+ String processInstanceId = processInstance.getId();
+ logger.debug("流程启动成功,流程ID:{}",processInstanceId);
+ Task task = bpmTaskService.selectTaskByProcessId(processInstanceId);
+ //如果指定了下一步执行环节,则将流程跳转到指定环节,并删除当前未执行的环节历史信息
+ if(!StringUtils.isNullOrEmpty(activity)){
+ bpmTaskService.jumpTask(processInstanceId,activity,StringUtils.isNullOrEmpty(next_claim)?"":next_claim);
+ bpmTaskService.removeHiTask(task.getId());
+ }else{
+ //流程签收,签收人为指定办理人
+ if(!StringUtils.isNullOrEmpty(next_claim))
+ bpmTaskService.claim(task.getId(), next_claim);
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{procDefKey, businessKey, processInstanceId, variables});
+ }catch (Exception e){
+ logger.warn("工作流启动失败,请联系管理员!");
+ }finally {
+ identityService.setAuthenticatedUserId(null);
+ }
+ return processInstance;
+ }
+
+ @Override
+ public List getProcessInstances(int page, int num, String procDefKey) {
+ return runtimeService.createProcessInstanceQuery().processDefinitionKey(procDefKey).listPage(page, num);
+ }
+
+ @Override
+ public void closeProcessInstance(String processInstanceId) {
+ runtimeService.suspendProcessInstanceById(processInstanceId);
+ }
+
+ @Override
+ public void openProcessInstance(String processInstanceId) {
+ runtimeService.activateProcessInstanceById(processInstanceId);
+ }
+
+ @Override
+ public ProcessDefinition getProcessDefinition(String processDefinitionId){
+ return repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
+ }
+
+ @Override
+ public InputStream findProcessPic(String procDefId) {
+ ProcessDefinition definition = getProcessDefinition(procDefId);
+ String source = definition.getDiagramResourceName();
+ InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(),source);
+ return inputStream;
+ }
+
+ @Override
+ public Job getJob(String processInstanceId) {
+ return managementService.createJobQuery().processInstanceId(processInstanceId).singleResult();
+ }
+
+ @Override
+ public int deleteJob(String jobId) {
+ return 0;
+ }
+
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmTaskServiceImp.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmTaskServiceImp.java
new file mode 100644
index 000000000..3555f1d2f
--- /dev/null
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/main/java/org/hswebframework/web/workflow/flowable/service/imp/BpmTaskServiceImp.java
@@ -0,0 +1,218 @@
+package org.hswebframework.web.workflow.flowable.service.imp;
+
+import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.impl.TaskServiceImpl;
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
+import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.hswebframework.utils.StringUtils;
+import org.hswebframework.web.workflow.flowable.entity.TaskInfo;
+import org.hswebframework.web.workflow.flowable.service.BpmTaskService;
+import org.hswebframework.web.workflow.flowable.service.BpmActivityService;
+import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
+import org.hswebframework.web.workflow.flowable.utils.JumpTaskCmd;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * @Author wangwei
+ * @Date 2017/8/7.
+ */
+@Service
+public class BpmTaskServiceImp extends FlowableAbstract implements BpmTaskService {
+
+ protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Resource
+ BpmActivityService bpmActivityService;
+
+ @Override
+ public List selectNowTask(String procInstId) {
+ return taskService.createTaskQuery().processInstanceId(procInstId).list();
+ }
+
+ @Override
+ public Task selectTaskByProcessId(String procInstId){
+ return taskService.createTaskQuery().processInstanceId(procInstId).singleResult();
+ }
+
+ @Override
+ public Task selectTaskByTaskId(String taskId){
+ return taskService.createTaskQuery().taskId(taskId).singleResult();
+ }
+
+ @Override
+ public String selectNowTaskName(String procInstId) {
+ List tasks = selectNowTask(procInstId);
+ if (tasks.size() == 1)
+ return tasks.get(0).getName();
+ else {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < tasks.size(); i++) {
+ if (i != 0)
+ builder.append(",");
+ builder.append(tasks.get(i).getName());
+ }
+ return builder.toString();
+ }
+
+ }
+
+ @Override
+ public String selectNowTaskId(String procInstId) {
+ List tasks = selectNowTask(procInstId);
+ if (tasks.size() == 1)
+ return tasks.get(0).getId();
+ else {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < tasks.size(); i++) {
+ if (i != 0)
+ builder.append(",");
+ builder.append(tasks.get(i).getId());
+ }
+ return builder.toString();
+ }
+ }
+
+ @Override
+ public void claim(String taskId, String userId){
+ Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+ if (task == null)
+ logger.warn("获取任务失败!");
+ if (!StringUtils.isNullOrEmpty(task.getAssignee())) {
+ logger.warn("该任务已被签收!");
+ }else taskService.claim(taskId, userId);
+ }
+
+
+ @Override
+ public List claimList(String userId){
+ List list = new ArrayList<>();
+ // 等待签收的任务
+ List todoList = taskService.createTaskQuery().taskCandidateUser(userId).includeProcessVariables().active().list();
+ return list;
+ }
+
+ @Override
+ public List todoList(String userId){
+ List list = new ArrayList<>();
+ // 已经签收的任务
+ List todoList = taskService.createTaskQuery().taskAssignee(userId).includeProcessVariables().active().list();
+ return list;
+ }
+
+ @Override
+ public void complete(String workFlowId, String userId, String activityId, String next_claim){
+ String taskId = selectNowTaskId(workFlowId);
+ Task task = taskService.createTaskQuery().taskId(taskId).includeProcessVariables().singleResult();
+ if (task == null)
+ logger.warn("任务不存在!");
+ String assignee = task.getAssignee();
+ if (null == assignee)
+ logger.warn("请先签收任务!");
+ if (!userId.equals(assignee)) {
+ logger.warn("只能完成自己的任务");
+ }
+ //完成此任务
+ if (activityId == null) {
+ taskService.complete(taskId);
+ }else{
+ jumpTask(workFlowId,activityId,next_claim);
+ }
+
+ //根据流程ID查找执行计划,存在则进行下一步,没有则结束工单
+ List execution = runtimeService.createExecutionQuery().processInstanceId(workFlowId).list();
+ if(execution.size()>0){
+ String tasknow = selectNowTaskId(workFlowId);
+ // 自定义下一执行人
+ if(!StringUtils.isNullOrEmpty(next_claim))
+ claim(tasknow, next_claim);
+ }
+ }
+
+ @Override
+ public void jumpTask(String procInstId, String activity, String next_claim){
+ Task task = selectTaskByProcessId(procInstId);
+ TaskServiceImpl taskServiceImpl=(TaskServiceImpl)taskService;
+ taskServiceImpl.getCommandExecutor().execute(new JumpTaskCmd(task.getExecutionId(), activity));
+ task = selectTaskByProcessId(procInstId);
+ if(null != task && !StringUtils.isNullOrEmpty(next_claim))
+ claim(task.getId(), next_claim);
+ }
+
+ @Override
+ public void setAssignee(String taskId,String userId){
+ taskService.setAssignee(taskId,userId);
+ }
+
+ @Override
+ public void endProcess(String procInstId){
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
+ ActivityImpl activity = bpmActivityService.getEndActivityImpl(processInstance.getProcessDefinitionId());
+ jumpTask(procInstId,activity.getId(),null);
+ }
+
+ @Override
+ public void removeHiTask(String taskId){
+ historyService.deleteHistoricTaskInstance(taskId);
+ }
+
+ @Override
+ public HistoricProcessInstance selectHisProInst(String procInstId) {
+ return historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult();
+ }
+
+ @Override
+ public Map getUserTasksByProcDefKey(String procDefKey){
+ String definitionId = repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).orderByProcessDefinitionVersion().desc().list().get(0).getId();
+ List activitiList = bpmActivityService.getUserTasks(definitionId);
+ Map map = new HashMap<>();
+ for(ActivityImpl activity:activitiList){
+ map.put(activity.getId(),activity.getProperty("name"));
+ }
+ return map;
+ }
+
+ @Override
+ public Map getUserTasksByProcInstId(String procInstId) {
+ String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult().getProcessDefinitionId();
+ List activitiList = bpmActivityService.getUserTasks(definitionId);
+ Map map = new HashMap<>();
+ for(ActivityImpl activity:activitiList){
+ map.put(activity.getId(),activity.getProperty("name"));
+ }
+ return map;
+ }
+
+ @Override
+ public void setVariables(String taskId, Map map) {
+ taskService.setVariables(taskId,map);
+ }
+
+ @Override
+ public void removeVariables(String taskId, Collection var2) {
+ taskService.removeVariables(taskId,var2);
+ }
+
+ @Override
+ public void setVariablesLocal(String taskId, Map map) {
+ taskService.setVariablesLocal(taskId,map);
+ }
+
+ @Override
+ public Map getVariables(String procInstId) {
+ List executions = runtimeService.createExecutionQuery().processInstanceId(procInstId).list();
+ String executionId = "";
+ for(Execution execution : executions){
+ if(StringUtils.isNullOrEmpty(execution.getParentId())){
+ executionId = execution.getId();
+ }
+ }
+ return runtimeService.getVariables(executionId);
+ }
+}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java
index 68a66d828..72ee5f224 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/ControllerTest.java
@@ -1,17 +1,86 @@
package org.hswebframework.web.workflow.flowable;
+import com.alibaba.fastjson.JSON;
+import org.activiti.engine.*;
+import org.activiti.engine.impl.RepositoryServiceImpl;
+import org.activiti.engine.impl.interceptor.SessionFactory;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
+import org.hswebframework.web.tests.SimpleWebApplicationTests;
+import org.hswebframework.web.workflow.flowable.service.BpmProcessService;
+import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* @Author wangwei
* @Date 2017/8/1.
*/
-@SpringBootApplication
-public class ControllerTest {
+public class ControllerTest extends SimpleWebApplicationTests {
- public static void main(String[] args) {
- SpringApplication.run(ControllerTest.class,args);
+ @Resource
+ protected RepositoryService repositoryService;
+ @Autowired
+ BpmProcessService bpmProcessService;
+
+ public ProcessInstance start() throws Exception {
+ Map map = new HashMap<>();
+ map.put("username", "admin");
+ return bpmProcessService.startProcessInstance("1", "test", null, null, "流程名", map);
}
+ @Test
+ public void test() {
+ ProcessInstance processInstance = null;
+ String aid = "";
+ try {
+ processInstance = start();
+ System.out.println("流程已启动:" + processInstance.toString());
+ int i = bpmProcessService.getProcessInstances(0, 10, "test").size();
+ System.out.println("当前活动流程数:" + i);
+ aid = processInstance.getActivityId();
+ System.out.println("当前流程节点ID_" + aid);
+ } catch (Exception e) {
+ System.out.println("启动流程失败" + e);
+ }
+ ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(repositoryService.createProcessDefinitionQuery().processDefinitionKey("test").singleResult().getId());
+ System.out.println("=========");
+ System.out.println(processDefinitionEntity.getActivities());
+ System.out.println(processDefinitionEntity.findActivity(aid));
+ System.out.println("=========");
+ }
+
+ @Configuration
+ public static class config {
+ @Autowired(required = false)
+ private List sessionFactories;
+
+ @Bean
+ public ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer() {
+ return configuration -> {
+ configuration
+ .setAsyncExecutorActivate(false)
+ .setJobExecutorActivate(false)
+ .setActivityFontName("宋体")
+ .setLabelFontName("宋体")
+ .setAnnotationFontName("宋体");
+
+ if (sessionFactories != null) {
+ configuration.setCustomSessionFactories(sessionFactories);
+ }
+ };
+ }
+ }
}
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/test/ServiceTest.java b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/test/ServiceTest.java
index 2f0eb261a..5c277a780 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/test/ServiceTest.java
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/java/org/hswebframework/web/workflow/flowable/test/ServiceTest.java
@@ -1,5 +1,6 @@
package org.hswebframework.web.workflow.flowable.test;
+import org.activiti.engine.repository.ProcessDefinition;
import org.hswebframework.web.workflow.flowable.utils.FlowableAbstract;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -15,7 +16,8 @@ public class ServiceTest extends FlowableAbstract {
@Test
public void getProcessDefinition(){
-
+ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("test").singleResult();
+ System.out.println(processDefinition);
}
}
\ No newline at end of file
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/application.yml b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/application.yml
index 7a766e2e9..10ea18e60 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/application.yml
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/application.yml
@@ -1,4 +1,3 @@
-
spring:
aop:
auto: true
@@ -14,7 +13,6 @@ spring:
logging:
level:
- org.hsweb: debug
org.flowable: debug
mybatis:
dynamic-datasource: false
diff --git a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/processes/SimpleProcess.bpmn20.xml b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/processes/SimpleProcess.bpmn20.xml
index d3a91a7ba..6f1896bbf 100644
--- a/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/processes/SimpleProcess.bpmn20.xml
+++ b/hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable/src/test/resources/processes/SimpleProcess.bpmn20.xml
@@ -1,56 +1,75 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+