美文网首页工作流
flowable表单引擎

flowable表单引擎

作者: Acamy丶 | 来源:发表于2018-08-25 21:48 被阅读0次

    flowable表单引擎作为一个独立的模块,也包括表单定义,部署等过程。

    1. API及与流程引擎的结合

    如下图所示,表单引擎也有一个独立的配置文件,配置类,配置引擎及三个Service.



    在实际使用中我们也是将其配置嵌入到流程引擎的配置中,配置形式如下(省略了非相关配置):

        <bean id="processEngineConfiguration"
              class="org.flowable.spring.SpringProcessEngineConfiguration">
            <property name="dataSource" ref="dataSource"/>
            <property name="transactionManager" ref="transactionManager"/>
            <property name="databaseSchemaUpdate" value="true"/>
            <property name="asyncExecutorActivate" value="false" />
            <property name="configurators">
                <list>
                    <bean class="org.flowable.form.engine.configurator.FormEngineConfigurator">
                        <property name="formEngineConfiguration">
                            <bean class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
                                <property name="dataSource" ref="dataSource"/>
                                <property name="databaseSchemaUpdate" value="true"/>
                            </bean>
                        </property>
                    </bean>
                </list>
            </property>
        </bean>
    
    
        <bean id="formRepositoryService" factory-bean="processEngine" factory-method="getFormEngineRepositoryService" />
    

    在应用重启时数据库中会增加act_fo_为前缀的六张数据库表格:
    act_fo_databasechangelog: Liquibase用来跟踪数据库变量的
    act_fo_databasechangeloglock: Liquibase用来保证同一时刻只有一个Liquibase实例在运行
    act_fo_form_definition:存储表单定义的信息
    act_fo_form_instance:存储用户填充后表单实例信息
    act_fo_form_deployment:存储表单部署元数据
    act_fo_form_resource:存储表单定义的资源

    2. 表单的定义

    表单定义文件是以.form为后缀, 内容格式为Json格式。如下示例所示。

    {
        "key": "form1",
        "name": "My first form",
        "fields": [
            {
                "id": "input1",
                "name": "Input1",
                "type": "text",
                "required": false,
                "placeholder": "empty"
            }
        ],
        "outcomes": [
            {
                "id": "null",
                "name": "Accept"
            },
            {
                "id": "null",
                "name": "Reject"
            }
        ]
    }
    

    该文件的key属性是其唯一性标识,表单引擎可以通过该key获取到它, 同时数据库对相同key会维护不同的版本。第二部分是表单字段数组,第三部分是表单结果。每一个表单字段都有id,name和type属性。id属性在同一个表单定义文件中必须唯一,当用户赋值时它会作为变量的名称,在上例中,也就是会创建名称为input1的变量,值由用户填入。同时表单结果也会以form_<form-identifier>_outcome获取得到,对于上例,用户选择的结果会赋值给form_form1_outcome, 我们可以通过${form_form1_outcome == "Accept"}表达式来验证表单结果是否为Accept。
    表单字段的type属性支持text, multi-line-text,integer,boolean,date等多种类型。

    3. 表单的使用

    首先在src/main/resources文件夹下创建test.form表单定义文件,内容如下:

    {
    "key": "form1",
    "name": "请假流程",
    "fields": [
                {
                "id": "startTime",
                "name": "开始时间",
                "type": "date",
                "required": true,
                "placeholder": "empty"
    
                },
                {
                "id": "endTime",
                "name": "结束时间",
                "type": "date",
                "required": true,
                "placeholder": "empty"
                },
                {
                "id": "reason",
                "name": "请假原因",
                "type": "text",
                "required": true,
                "placeholder": "empty"
                }
        ]
    }
    

    然后创建test-form.bpmn20.xml流程定义文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                 xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
                 xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
                 xmlns:flowable="http://flowable.org/bpmn"
                 typeLanguage="http://www.w3.org/2001/XMLSchema"
                 expressionLanguage="http://www.w3.org/1999/XPath"
                 targetNamespace="http://www.flowable.org/processdef">
    
        <process id="holidayRequest" name="Holiday Request" isExecutable="true">
    
            <startEvent id="startEvent" flowable:formKey="form1"/>
            <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
    
            <userTask id="approveTask" name="Approve or reject request" flowable:formKey="form1" flowable:candidateGroups="managers"/>
            <sequenceFlow sourceRef="approveTask" targetRef="holidayApprovedTask"/>
    
            <userTask id="holidayApprovedTask" name="Holiday approved" flowable:formKey="form1" flowable:assignee="employee"/>
            <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
    
            <endEvent id="approveEnd"/>
    
        </process>
    
    </definitions>
    

    上面的开始事件和两个用户任务都带有flowable:formKey属性。
    然后就可以创建测试类了,注意用runtimeService.startProcessInstanceWithForm方法启动带表单的流程,runtimeService.getStartFormModel查询流程启动时的表单信息; taskService.completeTaskWithForm填充表单完成任务,taskService.getTaskFormModel查询任务表单信息。具体测试类代码如下:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class FormTest {
        @Autowired
        private RepositoryService repositoryService;
    
        @Autowired
        private RuntimeService runtimeService;
    
        @Autowired
        private FormRepositoryService formRepositoryService;
    
        @Autowired
        private TaskService taskService;
    
        @Autowired
        private HistoryService historyService;
    
        /**
         * 流程以及表单的部署
         */
        @Test
        public void deployTest(){
            Deployment deployment = repositoryService.createDeployment()
                    .name("表单流程")
                    .addClasspathResource("flowable/test-form.bpmn20.xml")
                    .deploy();
    
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                    deploymentId(deployment.getId())
                    .singleResult();
            String processDefinitionId = processDefinition.getId();
            FormDeployment formDeployment = formRepositoryService.createDeployment()
                    .name("definition-one")
                    .addClasspathResource("flowable/test.form")
                    .parentDeploymentId(deployment.getId())
                    .deploy();
            FormDefinition formDefinition = formRepositoryService.createFormDefinitionQuery().deploymentId(formDeployment.getId()).singleResult();
            String formDefinitionId = formDefinition.getId();
    
    
    
            //启动实例并且设置表单的值
            String outcome = "shareniu";
            Map<String, Object> formProperties;
            formProperties = new HashMap<>();
            formProperties.put("reason", "家里有事");
            formProperties.put("startTime", Dates.format(new Date(), Dates.Pattern.DATE));
            formProperties.put("endTime", Dates.format(new Date(), Dates.Pattern.DATE));
            String processInstanceName = "shareniu";
            runtimeService.startProcessInstanceWithForm(processDefinitionId, outcome, formProperties, processInstanceName);
            HistoricProcessInstanceEntity historicProcessInstanceEntity = (HistoricProcessInstanceEntity )historyService.createHistoricProcessInstanceQuery()
                    .processDefinitionId(processDefinitionId)
                    .singleResult();
            String processInstanceId = historicProcessInstanceEntity.getProcessInstanceId();
    
    
    
            //查询表单信息
            FormModel fm = runtimeService.getStartFormModel(processDefinitionId, processInstanceId);
            System.out.println(fm.getId());
            System.out.println(fm.getKey());
            System.out.println(fm.getName());
            System.out.println(fm.getOutcomeVariableName());
            System.err.println(fm.getVersion());
            List<FormField> fields = fm.getFields();
            for (FormField ff : fields) {
                System.out.println("######################");
                System.out.println(ff.getId());
                System.out.println(ff.getName());
                System.out.println(ff.getType());
                System.out.println(ff.getPlaceholder());
                System.out.println(ff.getValue());
                System.out.println("######################");
    
            }
    
    
            //查询个人任务并填写表单
            Map<String, Object> formProperties2 = new HashMap<>();
            formProperties2.put("reason", "家里有事2222");
            formProperties2.put("startTime", Dates.format(new Date(), Dates.Pattern.DATE));
            formProperties2.put("endTime", Dates.format(new Date(), Dates.Pattern.DATE));
            formProperties2.put("days", "3");
            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
            String taskId = task.getId();
            String outcome2="牛哥";
            taskService.completeTaskWithForm(taskId, formDefinitionId, outcome2, formProperties2);
    
            //获取个人任务表单
            FormModel taskFM = taskService.getTaskFormModel(taskId);
        }
    
    }
    

    相关文章

      网友评论

        本文标题:flowable表单引擎

        本文链接:https://www.haomeiwen.com/subject/raagiftx.html