乐趣区

关于bpmn:Flowable实战五表单和流程变量

一、流程变量

  流程实例按步骤执行时,须要保留并应用一些数据,在 Flowable 中,这些数据称为变量(variable)。

  流程实例能够持有变量,称作流程变量(process variables)。

  为了应用效率,Flowable 将变量分为两种:运行时变量、历史变量。

1.1 运行时变量

  流程实例运行时的变量,存入 act_ru_variable 表中。在流程实例运行完结时,此实例的变量在表中删除。

  在流程实例创立及启动时,可设置流程变量。所有的 startProcessInstanceXXX 办法都有一个可选参数用于设置变量。例如,在 RuntimeService 中:

    ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);

  也能够在流程执行中退出变量。例如,(RuntimeService):

    void setVariable(String executionId, String variableName, Object value);
    void setVariableLocal(String executionId, String variableName, Object value);
    void setVariables(String executionId, Map<String, ? extends Object> variables);
    void setVariablesLocal(String executionId, Map<String, ? extends Object> variables);

  读取变量办法(请留神 TaskService 中有相似的办法。这意味着工作与执行一样,能够持有局部变量,其生存期为工作继续的工夫。)

    Map<String, Object> getVariables(String executionId);
    Map<String, Object> getVariablesLocal(String executionId);
    Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
    Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
    Object getVariable(String executionId, String variableName);
    <T> T getVariable(String executionId, String variableName, Class<T> variableClass);

留神:因为流程实例完结时,对应在运行时表的数据跟着被删除。所以,查问一个曾经完结流程实例的变量,只能在历史变量表中查找。

1.2 历史变量

  历史变量,存入 act_hi_varinst 表中。在流程启动时,流程变量会同时存入历史变量表中;在流程完结时,历史表中的变量依然存在。可了解为“永恒代”的流程变量。

  获取已实现的、id 为’XXX’的流程实例中,所有的 HistoricVariableInstances(历史变量实例),并以变量名排序。

    historyService.createHistoricVariableInstanceQuery()
      .processInstanceId("XXX")
      .orderByVariableName.desc()
      .list();

二、表单

  在理论业务中,流程随同着各种各样的表单,Flowable 引擎将表单数据对立作为流程变量存入变量表中。所以,对于 Flowable 引擎,能够齐全独立于表单运行,因为能够用流程变量替代表单数据。

  但个别的,咱们须要结构化的数据,表单依然是咱们举荐的用法。

  表单定义有两种办法,内置表单和内部表单。

2.1 内置表单

  以销假为例,XML 内容:

<process id="leave" name="销假流程 - 内置表单">
    <startEvent id="start">
          <extensionElements>
            <flowable:formProperty id="startDate" name="销假开始事件" type="date" 
              datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
            <flowable:formProperty id="endDate" name="销假完结事件" type="date" 
              datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
            <flowable:formProperty id="reason" name="销假起因" type="string" 
              required="true" readable="true" writeable="true"/>
            <flowable:formProperty id="leaveType" type="enum" name="销假类型">
              <flowable:value id="personalLeave" name="事假" />
              <flowable:value id="annualLeave" name="年假" />
            </flowable:formProperty>
          </extensionElements>
    </startEvent>
</process>

  应用办法:

    StartFormData FormService.getStartFormData(String processDefinitionId)

  或

    TaskFormData FormService.getTaskFormData(String taskId)

  内置表单理解即可,理论利用更多的是应用内部表单。

2.2 内部表单

  依据表单文件自行渲染的工作表单,称为内部表单。

2.2.1 XML 内容

    <process id="leave" name="销假流程 - 内置表单">
        <startEvent id="start" flowable:formKey="form1"></startEvent>
    </process>

留神:flowable:formKey=”form1″中的 ”form1″ 对应表单定义文件的 ”key” 值。

2.2.2 表单定义

  • 表单定义文件的后缀为.form。
  • 表单的 JSON 定义以 key、name 和 description 结尾。
  • 表单引擎通过属性 key 来分别表单在整个表单引擎中的惟一身份。对于起源雷同的同一个表单定义的版本零碎也是基于属性 key 运作的。
  • 第二局部是一个数组类型 fields,表单定义的字段在这里说明。
  • 第三局部是可选的,用来定义表单的后果 outcomes。示例如下:
{
    "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"
        }
    ]
}

2.2.3 部署表单

  在 springboot 环境下,resources/forms目录下任何.form 后缀的表单定义文件都会被主动部署。

  例如,将 2.2.2 表单定义内容保留为 leave.form 文件,放入 resources/forms 目录下。

留神:理论利用中,该当让前端流程设计器生成指定格局的表单定义文件,通过与前文提到的接口方式,更新部署流程定义及表单定义资源。

2.2.4 获取及提交表单参数

  实际上,渲染表单所需的所有数据都组装在上面两个办法:

    StartFormData FormService.getStartFormData(String processDefinitionId)
    TaskFormdata FormService.getTaskFormData(String taskId)

  能够通过上面两个办法提交表单参数:

    ProcessInstance FormService.submitStartFormData(String processDefinitionId, Map<String,String> properties)
    void FormService.submitTaskFormData(String taskId, Map<String,String> properties)

  表单参数 FormProperty 的具体信息:

public interface FormProperty {
  /**
   * 在{@link FormService#submitStartFormData(String, java.util.Map)}
   * 或{@link FormService#submitTaskFormData(String, java.util.Map)}
   * 中提交参数时应用的 key
   */
  String getId();

  /** 显示标签 */
  String getName();

  /** 在本接口中定义的类型,例如{@link #TYPE_STRING} */
  FormType getType();

  /** 可选。这个参数须要显示的值 */
  String getValue();

  /** 这个参数是否能够读取:在表单中显示,并可通过
   * {@link FormService#getStartFormData(String)}
   * 与{@link FormService#getTaskFormData(String)}
   * 办法拜访。*/
  boolean isReadable();

  /** 用户提交表单时是否能够蕴含这个参数?*/
  boolean isWritable();

  /** 输入框中是否必填这个参数 */
  boolean isRequired();}

2.2.5 获取及提交表单数据

  获取指定流程实例的表单数据的办法:

    FormModel RuntimeService.getStartFormModel(String processDefinitionId, String processInstanceId);

  提交表单数据的办法:

    // 附带表单数据启动流程实例
    ProcessInstance RuntimeService.startProcessInstanceWithForm(String processDefinitionId, String outcome, Map<String,Object> properties, String taskName);
    // 附带表单数据实现工作
    void TaskService.completeTaskWithForm(String taskId, String formDefinitionId, String outcome, Map<String,Object> properties);

  表单数据理论寄存在流程变量表,所以,用流程变量的办法同样能够获取及提交表单数据。

2.3 表单类型字段

  表单反对以下类型字段

  • text: 文本字段
  • multi-line-text: 多行文本字段
  • integer: 文本字段,然而只容许数字类型的值
  • boolean: 复选框字段
  • date: 日期字段
  • dropdown: 抉择框字段,定义字段时能够设置选项的值
  • radio-buttons: 单选字段,定义字段时能够设置选项的值
  • people: 抉择框字段,能够选中用户表里的一个用户
  • functional-group: 抉择框字段,能够选中分组表里的一个组
  • upload: 上传文件字段
  • expression: 一个标签,在标签文本中你能够使用 JUEL 表达式操作变量或其余动静的值

2.4 自定义表单字段类型

  在理论利用中,Flowable 提供的表单字段类型并不能齐全满足需要,往往咱们须要自定义表单字段类型。

  所有自定义字段类型须要继承一个表白类型抽象类“org.flowable.engine.form.AbstractFormType”。

  比方,定义一个 ” 卡片 ” 自定义类型:

public class CardFormType extends AbstractFormType {

    // 定义表单类型的标识符
    @Override
    public String getName() {return "card";}

    // 把表单中的值转换为理论的对象(理论解决逻辑依据具体业务而定)@Override
    public Object convertFormValueToModelValue(String propertyValue) {return propertyValue;}

    // 把理论对象的值转换为表单中的值(理论解决逻辑依据具体业务而定)@Override
    public String convertModelValueToFormValue(Object modelValue) {return (String) modelValue;
    }
    
}

  新建配置类,注册自定义字段类型解析类

@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter {
    @Bean
    public BeanPostProcessor activitiConfigurer() {return new BeanPostProcessor() {
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof SpringProcessEngineConfiguration) {List<AbstractFormType> customFormTypes = Arrays.<AbstractFormType>asList(new CardFormType());
                    ((SpringProcessEngineConfiguration)bean).setCustomFormTypes(customFormTypes);
                }
                return bean;
            }
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
        };
    }
}

2.5 自定义表单引擎

  Flowable 反对自定义表单引擎以适应各种场景。只须要实现接口 org.flowable.engine.impl.form.FormEngine,而后在引擎中注册自定义的表单引擎实现类即可。

public class MyFormEngine implements FormEngine {
    // 表单引擎的名称
    @Override
    public String getName() {return "MyFormEngine";}

    // 理论解决逻辑依据具体业务而定
    @Override
    public Object renderStartForm(StartFormData startFormData) {return "MyStartData";}

    // 理论解决逻辑依据具体业务而定
    @Override
    public Object renderTaskForm(TaskFormData taskFormData) {return "MyTaskData";}
}

  注册办法与自定义表单字段类型类似,在配置类中退出以下语句:

    List<FormEngine> customFormEngines = Arrays.<FormEngine>asList(new MyFormEngine());
    ((SpringProcessEngineConfiguration)bean).setCustomFormEngines(customFormEngines);

  应用办法:

    Object FormService.getRenderedStartForm(String processDefinitionId, "myFormEngine");
    Object FormService.getRenderedTaskForm(String taskId);

三、小结

  通过本篇,咱们理解到了表单和流程变量的具体应用,同样的,在理论业务应用中,还须要不少优化。比方,咱们能够在 formKey 中保留通用的 key,通过算法或转换失去理论须要应用的表单模板,在一般屏幕尺寸的 Web 利用中显示一个表单,在手机等小屏幕中显示另一个表单。还有下一篇将讲到的“集成 JPA”,进一步对表单和流程变量的应用做出优化。

退出移动版