Flowable 自定义业务表单

适用版本:PIGX 5.10 及以上
流程引擎:Flowable
表单类型:自定义表单(业务表单)
最后更新:2025 年 10 月

自定义业务表单示例
演示代码

项目已经提供如下演示代码,二开请先阅读相关代码逻辑和如下开发规范

前端页面与路由配置

页面类型文件路径路由路径功能描述操作权限
列表页/flow/oaLeave/index.vue/flow/oaLeave展示请假记录列表,支持管理操作查看、编辑、删除(基于权限)
创建页/flow/oaLeave/create.vue/flow/oaLeave/create填写请假表单并发起审批流程仅限创建者
详情页/flow/oaLeave/detail.vue/flow/oaLeave/detail/:id查看流程详情、执行审批操作流程参与者及审批人

后端服务实现

  • 控制器类BpmOaLeaveController
    负责处理前端请求,包括列表查询、新增、详情获取等接口。

  • 业务逻辑类BpmOaLeaveServiceImpl
    实现请假流程的核心业务逻辑,如数据校验、流程启动、状态更新等。

第一部分:核心概念

1.1 自定义表单工作流程

业务需求分析 ↓ 创建业务表 (包含 process_instance_id) ↓ 前端页面开发 (create.vue & detail.vue) ↓ Flowable 流程定义配置 ↓ 后端服务实现 (Service & Controller) ↓ 流程启动与监听 (IProcessInstanceStatusEventService)

1.2 关键组件

组件职责关键字段
业务表存储业务数据process_instance_id
create.vue表单编辑发起流程入口
detail.vue信息展示审批流程查看
流程定义控制流程逻辑LEAVE
Service业务处理IProcessInstanceStatusEventService

第二部分:数据库设计

2.1 业务表创建规范

必需字段

字段类型说明约束
idBIGINT主键NOT NULL, PK
process_instance_idVARCHAR(64)流程实例编号(必须)必须
create_byVARCHAR(64)创建者DEFAULT ''
create_timeDATETIME(6)创建时间DEFAULT CURRENT_TIMESTAMP(6)
update_byVARCHAR(64)更新者DEFAULT ''
update_timeDATETIME(6)更新时间支持自动更新
del_flagCHAR(1)删除标记DEFAULT '0'
tenant_idBIGINT租户编号DEFAULT 0

业务字段

根据具体业务需求添加,以请假表单为例:

字段类型说明
usernameVARCHAR(255)申请人
leave_typeSMALLINT请假类型
leave_reasonVARCHAR(255)请假原因
start_timeDATETIME(6)开始时间
end_timeDATETIME(6)结束时间
leave_daySMALLINT请假天数
leave_statusSMALLINT请假结果/流程状态

表创建示例

CREATE TABLE `bpm_oa_leave` (
  `id` BIGINT NOT NULL COMMENT '主键',
  `process_instance_id` VARCHAR(64) DEFAULT NULL COMMENT '流程实例编号',
  `username` VARCHAR(255) NOT NULL COMMENT '申请人',
  `leave_type` SMALLINT NOT NULL COMMENT '请假类型',
  `leave_reason` VARCHAR(255) DEFAULT NULL COMMENT '请假原因',
  `start_time` DATETIME(6) NOT NULL COMMENT '开始时间',
  `end_time` DATETIME(6) NOT NULL COMMENT '结束时间',
  `leave_day` SMALLINT NOT NULL COMMENT '请假天数',
  `leave_status` SMALLINT DEFAULT NULL COMMENT '请假结果',
  `create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
  `create_time` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
  `update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
  `update_time` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
  `del_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
  `tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='请假申请表';

第三部分:前端实现

3.1 页面架构

页面文件路径路由用途操作权限
列表/flow/oaLeave/index.vue/flow/oaLeave数据展示和记录管理查看、编辑、删除
创建/flow/oaLeave/create.vue/flow/oaLeave/create新增表单、发起流程仅创建者
详情/flow/oaLeave/detail.vue/flow/oaLeave/detail/:id流程审批、信息查看参与者、审批人

3.2 页面功能说明

列表页 (index.vue)

主要功能

  • 数据分页展示
  • 流程状态查询
  • 新增/编辑/删除操作
  • 流程详情链接

关键方法

// 分页查询
getBpmOaLeavePage(params)

// 查看详情
handleDetail(row)

// 进入编辑
handleEdit(row)

// 删除
handleDelete(id)

创建页 (create.vue)

主要功能

  • 表单编辑与表单提交
  • 数据验证
  • 自动发起流程
  • 保存表单数据及流程实例 ID

核心逻辑

// 提交表单
handleSubmit() {
  // 1. 表单验证
  // 2. 调用后端 save() 方法
  // 3. 自动保存业务数据
  // 4. 自动启动流程
  // 5. 返回流程实例 ID
}

详情页 (detail.vue)

主要功能

  • 以只读形式展示表单数据
  • 显示流程进度
  • 审批人审批操作入口
  • 流程历史记录查看

特殊处理

  • 根据角色显示不同权限操作按钮
  • 展示流程审批意见

3.3 流程回调 Props 参数

核心机制

在流程审批过程中,流程引擎会以组件 Props 的方式将流程上下文参数回调给业务表单。开发者可以利用这些参数动态控制表单的显隐、只读状态、数据加载等行为。

详情页 Props(detail.vue)

审批节点渲染详情页时,流程引擎会注入以下参数:

参数类型说明使用场景
idstring业务记录主键通过 ID 加载业务数据
businessKeystring流程业务标识关联流程与业务数据
processInstanceIdstring流程实例编号查询流程状态、加载关联数据
readonlyboolean是否只读(默认 true控制表单是否可编辑
nodeRecord<string, any>当前流程节点信息根据节点类型展示不同操作按钮
// detail.vue Props 定义
interface Props {
  id?: string;
  businessKey?: string;
  processInstanceId?: string;
  readonly?: boolean;
  node?: Record<string, any>;
}

const props = withDefaults(defineProps<Props>(), {
  readonly: true
});

创建页 Props(create.vue)

发起节点或驳回重新提交时,流程引擎会注入以下参数:

参数类型说明使用场景
flowHelperobject流程辅助对象提供 validate() 校验审批人、getFlowData() 获取流程数据
processInstanceIdstring流程实例编号驳回后重新提交时,用于加载已有数据
readonlyboolean是否只读控制表单是否可编辑
// create.vue Props 定义
const props = defineProps<{
  flowHelper?: any;
  processInstanceId?: string;
  readonly?: boolean;
}>();

Props 使用示例

根据 readonly 控制表单可编辑状态

<el-input v-model="formData.leaveReason" :disabled="props.readonly" />

利用 flowHelper 提交流程数据

const submitForm = async () => {
  // 1. 表单校验
  await formRef.value.validate();

  // 2. 审批人校验
  if (props.flowHelper && !props.flowHelper.validate()) {
    return;
  }

  // 3. 合并流程数据提交
  let submitData = { ...formData };
  if (props.flowHelper) {
    const flowData = props.flowHelper.getFlowData();
    submitData = { ...submitData, ...flowData };
  }

  await addObj(submitData);
};

通过 processInstanceId 加载数据(驳回重新提交)

onMounted(() => {
  if (props.processInstanceId) {
    // 驳回后重新提交场景,通过流程实例编号加载已有数据
    isEdit.value = true;
    getOaLeaveData({ processInstanceId: props.processInstanceId });
  }
});

利用 node 信息控制按钮显隐

<!-- 根据节点信息动态展示审批操作 -->
<template v-if="props.node?.type === 'userTask'">
  <el-button type="success">同意</el-button>
  <el-button type="danger">拒绝</el-button>
</template>

3.4 路由配置示例

// 路由配置参考
{
  path: 'oaLeave',
  component: () => import('@/views/flow/oaLeave/index'),
  meta: {
    title: '请假申请',
    permissions: ['bpm:oaLeave:query']
  },
  children: [
    {
      path: 'create',
      component: () => import('@/views/flow/oaLeave/create'),
      meta: { title: '发起请假申请' }
    },
    {
      path: 'detail/:id',
      component: () => import('@/views/flow/oaLeave/detail'),
      meta: { title: '请假申请详情' }
    }
  ]
}

第四部分:Flowable 流程定义

4.1 流程定义配置

基础配置

配置项说明样例重要性
流程标识 (Process Key)业务代码必须匹配LEAVE⭐⭐⭐ 必须
流程名称用户可见的流程名称请假申请流程一般
版本流程版本号v1版本管理
表单类型选择自定义表单自定义表单必须

表单关联配置

节点表单类型表单路径说明
发起节点编辑表单/flow/oaLeave/create.vue用户填写表单
审批节点查看表单/flow/oaLeave/detail.vue审批人查看详情

4.2 流程节点设计原则

发起节点

  • 配置表单为 create.vue
  • 允许表单编辑
  • 用户填写业务数据

审批节点

  • 配置表单为 detail.vue
  • 只读表单展示
  • 展示审批指令(同意/拒绝)

回调配置

  • 配置状态变更监听
  • 触发 IProcessInstanceStatusEventService 回调

第五部分:后端实现

5.1 Service 层设计

必须实现的接口

/**
 * 流程状态事件监听接口
 * 实现此接口以响应流程状态变更
 */
public interface IProcessInstanceStatusEventService {
    
    /**
     * 获取监听的流程定义标识
     * 返回值必须与流程定义中的 Process Key 一致
     */
    String getFlowId();
    
    /**
     * 处理流程状态变更回调
     */
    void handleStatusEvent(ProcessInstanceParamDto paramDto);
}

Service 实现示例

方法功能调用时机返回值
getFlowId()返回流程标识服务启动时注册"LEAVE"
handleStatusEvent()处理状态变更流程状态改变时void
saveAndStartProcess()保存数据并启动流程用户提交表单时业务实体

5.2 Controller 层设计

RESTful API 规范

HTTP方法端点功能说明
POST/api/bpmOaLeavesave()保存并启动流程
GET/api/bpmOaLeavegetBpmOaLeavePage()分页查询
GET/api/bpmOaLeave/{id}getDetails()获取详情
PUT/api/bpmOaLeaveupdateById()更新记录
DELETE/api/bpmOaLeave/{id}removeById()删除记录

核心方法说明

save() - 保存并发起流程

请求流程: 前端 create.vue ↓ POST 表单数据 Controller.save() ↓ Service.saveAndStartProcess() ↓ 1. 保存业务数据到数据库 2. 调用流程引擎启动流程 3. 获取流程实例 ID 4. 更新 process_instance_id 字段 ↓ 返回业务实体(包含 process_instance_id) ↓ 前端跳转到流程进度页

5.3 核心业务逻辑

启动流程的完整流程

步骤操作关键代码
1保存业务数据baseMapper.insert(bpmOaLeave)
2构建启动参数ProcessInstanceParamDto
3设置流程参数用户信息、自定义参数
4调用流程引擎flowApiFlowService.startProcessInstance()
5获取流程实例 IDstringR.getData()
6更新业务数据baseMapper.updateById() 写入 process_instance_id

流程回调处理

事件触发时机处理方法更新字段
流程启动用户提交表单saveAndStartProcess()process_instance_id
流程状态变更审批人操作handleStatusEvent()leave_status
流程完成所有审批通过handleStatusEvent()leave_status

第六部分:集成步骤

6.1 快速集成流程

第一步:数据库准备

-- 创建业务表
CREATE TABLE `bpm_oa_leave` (...)

-- 创建索引
CREATE INDEX idx_process_instance_id ON bpm_oa_leave(process_instance_id);

第二步:代码生成

  • 使用 PIGX 代码生成器生成 Entity、Mapper、Service、Controller
  • 选择模板类型为标准CRUD
  • 生成路径:com.pigx.bpm.oaleave.*

第三步:服务层改造

修改 BpmOaLeaveServiceImpl,实现 IProcessInstanceStatusEventService 接口:

@Service
public class BpmOaLeaveServiceImpl extends ServiceImpl<BpmOaLeaveMapper, BpmOaLeaveEntity>
        implements BpmOaLeaveService, IProcessInstanceStatusEventService {
    
    @Override
    public String getFlowId() {
        return "LEAVE";  // 与流程定义中的 Process Key 保持一致
    }
    
    @Override
    public void handleStatusEvent(ProcessInstanceParamDto paramDto) {
        // 处理流程状态变更
    }
    
    @Override
    public BpmOaLeaveEntity saveAndStartProcess(BpmOaLeaveEntity bpmOaLeave) {
        // 保存业务数据并启动流程
    }
}

第四步:前端页面开发

  • 创建 create.vue(表单编辑)
  • 创建 detail.vue(信息展示)
  • 配置路由

第五步:Flowable 流程配置

  • 创建流程定义,设置 Process Key = LEAVE
  • 配置发起节点表单指向 create.vue
  • 配置审批节点表单指向 detail.vue
  • 配置状态变更回调

第六步:测试验证

  • 测试表单提交和流程启动
  • 验证流程实例 ID 正确保存
  • 测试流程状态回调和数据更新
  • 验证多个流程定义不相互干扰

第七部分:关键要点

7.1 必须遵循的规范

必做项

  1. 业务表必须包含 process_instance_id 字段

    • 用于关联流程实例
    • 类型:VARCHAR(64)
    • 默认值:NULL
  2. Service 必须实现 IProcessInstanceStatusEventService 接口

    • 实现 getFlowId() 方法
    • 实现 handleStatusEvent() 方法
    • Flow ID 必须与流程定义的 Process Key 一致
  3. 前端必须区分创建和详情页

    • create.vue:可编辑表单
    • detail.vue:只读表单
  4. 流程定义标识 (Process Key) 必须唯一

    • 不同业务使用不同的 Flow ID
    • Service 层使用相同的 Flow ID 进行监听