# 工作流开发指南

### 工作流开发

#### 工作流开发整体思路

* 流程设计
* 实现启动接口
* 调用实现类
* 启动工作流
  

一、流程设计

1 新建工作流并填写对应的信息
![](/assets/wfl_demo_1.png)
![](/assets/wfl_demo_2.png)

\*这里需要注意分类跟唯一标识这个字段，后面编写实现类的时候需要传入分类跟唯一标识。

2 保存之后点击对应工作流的第一个图标，即可编辑对应的工作流节点，下面将详细介绍一些常用的工作流属性（新建工作流的时候可参考已实现工作流）

* ID:自动生成，节点唯一标识
* 名称:当前节点中文描述
* 文档：消息机制，可在上下文中取到，如：我是${name},name为实现类里面配置的参数
* 审批方式：默认为全部通过
* 审批方式变量：当审批方式选择一定比例时，可设置变量如0.4，表示当审批人数达到这个比例后将会通过

* 审批规则：选择对应的审批人，可在审批规则中定义

* 加签：若勾选，则当前审批者可添加审批人
* 表单url：表示审批流程中可插入的页面，能让审判者读阅
* 执行监听器：执行监听器start跟end两种分别代表在该节点之前跟在该节点之后，在代理表达式里面可调用对应自己写的java类，格式如下：${endActionEventTask}
* 任务监听器：任务监听器可参考执行监听器

下图是一个完整的工作流流程设计
![](/assets/wfl_demo_3.png)

二、实现启动接口

* 编写一个自己的实现类，实现IActivitiCommonService接口  

![](/assets/wfl_demo_4.png)

实现类代码如下

```java

@Service
@Transactional
public class PrjActivitStartServiceImpl implements IActivitiCommonService
 { 
    private static final String workFlowType = "PRJ_PROJECT"; 
    @Autowired     
    private IActivitiService activitiService;
    @Autowired 
    private IReProcdefService reProcdefService;
    @Autowired 
    private PrjProjectService projectService;
    @Autowired 
    private PrjProjectMeetingMapper meetingMapper; 
    @Override 
    public String getWorkFlowType() { return workFlowType; } 
    @Override 
    public void process(IRequest iRequest, List list, Map params) 
    {
         ProcessInstanceCreateRequest processInstanceCreateRequest = getProcessInstanceCreateRequest((PrjProject)list.get(0),iRequest);
         activitiService.startProcess(iRequest, processInstanceCreateRequest);
    }
     private ProcessInstanceCreateRequest getProcessInstanceCreateRequest(PrjProject prjProject, IRequest iRequest) 
    { 
        ProcessInstanceCreateRequest createRequest = new ProcessInstanceCreateRequest();
        PrjProject project=projectService.selectByPrimaryKey(iRequest,prjProject); 
        ReProcdef reProcdefs ;  
        reProcdefs = reProcdefService.queryReProcdef("PRJ_PROJECT_APPROVE","PRJ_PROJECT");  
        String id = reProcdefs.getId_();
        String name = reProcdefs.getName_(); 
        createRequest.setProcessDefinitionId(id);                       
        createRequest.setBusinessKey(prjProject.getProjectId().toString()); 
        List<RestVariable> variables = new ArrayList<RestVariable>();
        List<RestVariable> transientVariables = new ArrayList<RestVariable>();
        RestVariable restVariable1 = new RestVariable();
        RestVariable restVariable2 = new RestVariable(); 
        RestVariable restVariable3 = new RestVariable(); 
        RestVariable restVariable4 = new RestVariable();
        RestVariable restVariable5 = new RestVariable(); 
        RestVariable restVariable6 = new RestVariable(); 

        restVariable1.setName("processDefinitionId"); 
        restVariable1.setValue(id); variables.add(restVariable1); 
        restVariable2.setName("prjProject"); 
        JSONObject jsonObject= new JSONObject().fromObject(prjProject);
        restVariable2.setValue(jsonObject.toString());                                          
        variables.add(restVariable2); 
        restVariable3.setName("iRequest");
        restVariable3.setValue(iRequest); 
        variables.add(restVariable3); 
        restVariable4.setName("projectNum");
        restVariable4.setValue(project.getProjectNumber());
        variables.add(restVariable4);         
        restVariable5.setName("projectName"); 
        restVariable5.setValue(project.getProjectName());
        variables.add(restVariable5);     
        restVariable6.setName("startUserName"); 
        restVariable6.setValue(iRequest.getEmployeeCode()); 
        variables.add(restVariable6);
        RestVariable restVariable7 = new RestVariable(); 
        RestVariable restVariable8 = new RestVariable();
        RestVariable restVariable9 = new RestVariable();         
        restVariable7.setName("documentCategory"); 
        restVariable7.setValue(project.getDocumentCategory());
        variables.add(restVariable7);         
        restVariable8.setName("documentType"); 
        restVariable8.setValue(project.getDocumentType()); 
        variables.add(restVariable8); 
        restVariable9.setName("documentId");
        restVariable9.setValue(project.getProjectId()); 
        variables.add(restVariable9);
        RestVariable restVariable10 = new RestVariable(); 
        restVariable10.setName("doubleFlag");
        PrjProjectMeeting meeting = new PrjProjectMeeting(); 
        meeting.setProjectId(prjProject.getProjectId()); 
        List<PrjProjectMeeting> list = meetingMapper.select(meeting);
        if(list.size() >0) { 
           restVariable10.setValue("Y"); 
        }
        else{         
         restVariable10.setValue("N");
        }
        variables.add(restVariable10);
        RestVariable restVariable11 = new RestVariable();
        restVariable11.setName("pName"); 
        restVariable11.setValue(name);
        variables.add(restVariable11);
        createRequest.setVariables(variables);
        createRequest.setTransientVariables(transientVariables);
        return createRequest; 
}}

```

* 关键参数讲解：
  private static final String workFlowType = "PRJ\_PROJECT";在启动工作流的时候工作流会根据这个类型找到对应的实现类，
  在启动工作流的时候会调用process方法，该方法会调用getProcessInstanceCreateRequest方法，在getProcessInstanceCreateRequest方法里面
  可以将自己工作流所需参数都放到里面去，可以在后面的流程中取到自己所需参数。
  reProcdefs = reProcdefService.queryReProcdef\("PRJ\_PROJECT\_APPROVE","PRJ\_PROJECT"\);参数一为创建工作流时候的唯一标志，参数二为工作流的分类

三 调用实现类并启动工作流

```
Map<String,Object> params = new HashMap<String,Object>();
params.put("workFlowType","PRJ_PROJECT");
activitiStartService.start(iRequest,projects,params);

```

* 代码解析

params.put\("workFlowType","PRJ\_PROJECT"\);放入的为工作流实现类的类型

#### 工作流功能详解
一、配置审批方式

![](/assets/wfl_demo_2-1.png)

如上图，在选择审批方式的时候，一共有五种审批方式，这里面的审批方式可在下图中的功能里面配置，如下图所示，
![](/assets/wfl_demo_2-2.png)
![](/assets/wfl_demo_2-3.png)

这里面配置的审批方式会在设计节点的时候查询出来，可在这里删除或者添加新的审批方式，审批方式中的通过条件中，里面的一个变量为系统内置变量，具体含义可在IActivitiConstants.java文件中查看，如下图所示，
![](/assets/wfl_demo_2-4.png)

二、配置审批规则
在流程设计的时候，点击审批规则会弹出下面的选择框，如下图所示，
![](/assets/wfl_demo_2-5.png)
审批规则是一个combobox，这里面的选项是在审批规则的功能里面进行配置，如下图所示
![](/assets/wfl_demo_2-6.png)
![](/assets/wfl_demo_2-7.png)
我们可以看到，这里我们需要配置三个选项，分别是代码，描述，表达式，这里表达式对应某个变量或者我们后台写的service，我们通过service取得对应这个审批规则下所有的审批人员，我们可以看到方法后面还跟了一个参数，这个参数在我们选择的时候会放到表单属性里面，在我们介绍表单属性的会具体介绍

三、表单属性
点击表单属性，弹出下图，
![](/assets/wfl_demo_2-9.png)
这里面可以根据业务场景自行配置表单属性，但是这里有两个比较重要的表单属性是必须要配置的，一个为配置审批规则的时候自动生成的表单属性，一个为配置审批选项时需要配置的审批按钮（如：同意，拒绝），分别如下图所示，
![](/assets/wfl_demo_2-10.png)
![](/assets/wfl_demo_2-11.png)

第一个图里面的表单属性是在我们配置完审批规则的时候会自动生成的，无须我们自行配置，我们可以看到我们这里选择的是按岗位进行审批，所以这里面生成一个岗位代码，工作流在找节点的时候就会调用我们配置的service传入这个code进行查询，将该节点的审批人员查询出来。


第二图为审批人员在审批页面可点击的审批按钮，我们配置了哪些，在审批页面就会出来对应哪些按钮，加签与转交跟这个是一样的，也会生成对应的按钮，这里需要注意的是对应的按钮代码是固定的，我们需要配置对应的代码才会出现对应的按钮







