Skip to content

引擎三分钟入门

一个 Go 库加 6 张表。建库、连库、发实例——你写的是业务代码,不是流程代码。

1. 初始化数据库

引擎只维护自己的 6 张工作流表,用户/角色/部门等系统表由宿主应用负责。

PostgreSQL:

bash
psql -d rulego_bpm -f scripts/00.init_bpm_pg.sql

MySQL:

bash
mysql -u root -p rulego_bpm < scripts/00.init_bpm_mysql.sql

初始化脚本会先删除同名表,只能用于全新数据库。

建表清单:wf_process(流程定义)、wf_instance / wf_hi_instance(实例运行时/历史)、wf_task / wf_hi_task(任务运行时/历史)、wf_task_assignee(候选人池)。每张表的作用见数据模型

2. 启动引擎并部署流程

go
package main

import (
	"context"
	"log"

	"github.com/rulego/rulego-bpm/components"
	"github.com/rulego/rulego-bpm/config"
	"github.com/rulego/rulego-bpm/model"
	"github.com/rulego/rulego-bpm/service"
	"github.com/rulego/rulego-bpm/types/dto"
	"github.com/rulego/rulego-bpm/types/enums"
)

func main() {
	ctx := context.Background()

	// 1. 数据库配置并启动引擎
	cfg := &config.Config{
		Database: &config.DatabaseConfig{
			Driver: "postgres",
			Dsn:    "host=127.0.0.1 user=postgres password=postgres dbname=rulego_bpm port=5432 sslmode=disable",
		},
	}
	engine := service.NewWorkflowEngine("demo", cfg)
	if err := engine.Start(ctx); err != nil {
		log.Fatalf("启动引擎失败: %v", err)
	}
	defer engine.Stop(ctx)

	// 2. 注册工作流节点组件(userTask/serviceTask/automation/...)
	//    identityService 生产环境必须换成对接真实组织架构的实现
	if err := components.RegisterWorkflowComponents(
		engine.GetTaskService(),
		engine.GetIdentityService(),
		engine.GetRuntimeService(),
		nil, // CCTaskCreatedListener,可选
		nil, // TaskEventListener,可选
		nil, // RuleChainExecutor,automation 跨池调用时传入
	); err != nil {
		log.Fatalf("注册组件失败: %v", err)
	}

	// 3. 部署流程定义(DSL 为 rulego 规则链 JSON)
	_, err := engine.GetProcessService().Deploy(ctx, &model.WfProcess{
		ProcessKey:     "leave_approval",
		Name:           "请假审批",
		DefinitionJSON: leaveApprovalDSL, // 见 examples/leave_approval
		TenantID:       "default",
		CreatedBy:      "admin",
	}, true)
	if err != nil {
		log.Fatalf("部署流程失败: %v", err)
	}

	// 4. 发起流程实例
	instanceID, err := engine.GetRuntimeService().StartProcessInstanceByKey(
		ctx,
		service.Identity{UserId: "emp001", TenantId: "default"},
		"leave_approval",
		"leave_emp001_1", // 业务键
		map[string]interface{}{"days": 5, "managerId": "mgr001", "reason": "家中事务"},
		false,
	)
	if err != nil {
		log.Fatalf("发起流程失败: %v", err)
	}
	_ = instanceID
}

3. 审批人处理待办

go
tasks, _, err := engine.GetTaskService().GetTaskList(ctx, &dto.TaskQuery{
	Assignee: "mgr001",
	PageRequest: dto.PageRequest{
		Status:   []string{string(enums.TaskStatusPending), string(enums.TaskStatusActive)},
		PageSize: 10,
	},
})
if err != nil || len(tasks) == 0 {
	return
}

err = engine.GetTaskService().CompleteWithApproval(ctx, &service.ApprovalRequest{
	TaskID:         tasks[0].ID,
	UserID:         "mgr001",
	ApprovalResult: enums.ApprovalResultApproved,
	Comment:        "同意",
})

完整可运行示例(或签、并行会签、顺序会签)见仓库 examples/leave_approval 目录(Gitee / GitHub)。

4. 接入组织架构(IdentityService)

引擎不绑定任何用户体系。按角色/部门/主管发起的审批任务,办理人统一通过 service.IdentityService 接口解析:

go
// 实现 8 个方法,对接你自己的组织架构表
type OrgIdentityService struct {
	db *gorm.DB
}

func (s *OrgIdentityService) GetUserIDsByRoleID(ctx context.Context, tenantID, roleID string) ([]string, error) {
	var userIDs []string
	err := s.db.WithContext(ctx).
		Table("user_roles").
		Where("tenant_id = ? AND role_id = ?", tenantID, roleID).
		Pluck("user_id", &userIDs).Error
	return userIDs, err
}
// 其余方法:GetUserIDsByDepartmentID / GetDepartmentManagerUserID /
//          GetUserManagerID / GetUserManagerHierarchy /
//          GetUserDepartmentID / GetRoleIDsByUserID / GetUserIDsByGroupID

通过 Builder 注入:

go
engine, err := service.NewWorkflowEngineBuilder().
	SetName("demo").
	SetConfig(cfg).
	SetIdentityService(&OrgIdentityService{db: gormDB}).
	Build()

TIP

不想写组织架构对接?直接用 gflow——它内置了用户/角色/部门/岗位/多租户的完整实现和全部界面,见 gflow 平台体验

rulego-bpm 基于 Apache-2.0 许可开源 · gflow 商业授权