Skip to content

createProcessDefinitionQuery

Flowable 7.1.0 摘要:创建流程定义查询对象,用于查询已部署的流程定义。

方法签名与说明

ProcessDefinitionQuery createProcessDefinitionQuery()

创建一个流程定义查询构建器,用于根据各种条件查询已部署的流程定义。支持链式调用,可组合多个查询条件。

Returns:

  • ProcessDefinitionQuery - 流程定义查询构建器

常见使用场景

1. 流程定义列表展示

在企业流程管理后台,展示所有已部署的流程定义列表,支持按名称、类别、版本等条件筛选。

2. 获取最新版本流程

在启动流程时,需要获取指定流程Key的最新版本,确保使用最新的流程定义。

3. 多租户流程查询

在SaaS平台中,查询特定租户的所有流程定义,实现租户隔离。

4. 流程分类管理

按业务类别(如人事、财务、采购等)查询和管理流程定义。

Kotlin + Spring Boot 调用示例

示例1:查询所有流程定义

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

@Service
class ProcessDefinitionQueryService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 查询所有流程定义
     * 企业场景:流程管理后台展示所有可用流程
     */
    fun getAllProcessDefinitions(): List<Map<String, Any>> {
        val processDefinitions = repositoryService.createProcessDefinitionQuery()
            .orderByProcessDefinitionName()
            .asc()
            .list()
        
        return processDefinitions.map { pd ->
            mapOf(
                "id" to pd.id,
                "key" to pd.key,
                "name" to pd.name,
                "version" to pd.version,
                "category" to pd.category,
                "deploymentId" to pd.deploymentId,
                "isSuspended" to pd.isSuspended
            )
        }
    }
}

示例2:获取最新版本的流程定义

kotlin
import org.flowable.engine.RepositoryService
import org.flowable.engine.repository.ProcessDefinition
import org.springframework.stereotype.Service

@Service
class LeaveProcessService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 获取请假流程的最新版本
     * 企业场景:员工提交请假申请时,自动使用最新版本的流程
     */
    fun getLatestLeaveProcess(): ProcessDefinition? {
        return repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey("leave-approval-process")
            .latestVersion()
            .singleResult()
    }
    
    /**
     * 启动最新版本的请假流程
     */
    fun startLatestLeaveProcess(employeeId: String, leaveDays: Int): String {
        val processDefinition = getLatestLeaveProcess()
            ?: throw IllegalStateException("请假流程尚未部署")
        
        println("使用流程版本: V${processDefinition.version}")
        
        // 启动流程实例...
        return processDefinition.id
    }
}

示例3:按类别查询流程定义

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

data class ProcessCategory(
    val category: String,
    val displayName: String,
    val processCount: Int,
    val processes: List<ProcessInfo>
)

data class ProcessInfo(
    val key: String,
    val name: String,
    val version: Int,
    val isActive: Boolean
)

@Service
class ProcessCategoryService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 按业务类别查询流程
     * 企业场景:在流程中心按模块分类展示流程
     */
    fun getProcessesByCategories(): List<ProcessCategory> {
        val categories = listOf(
            "人事管理" to "HR",
            "财务管理" to "Finance",
            "采购管理" to "Procurement",
            "合同管理" to "Contract"
        )
        
        return categories.map { (displayName, categoryCode) ->
            val processes = repositoryService.createProcessDefinitionQuery()
                .processDefinitionCategory(categoryCode)
                .latestVersion() // 只获取最新版本
                .orderByProcessDefinitionName()
                .asc()
                .list()
            
            ProcessCategory(
                category = categoryCode,
                displayName = displayName,
                processCount = processes.size,
                processes = processes.map { pd ->
                    ProcessInfo(
                        key = pd.key,
                        name = pd.name,
                        version = pd.version,
                        isActive = !pd.isSuspended
                    )
                }
            )
        }
    }
}

示例4:多租户流程查询

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

@Service
class TenantProcessQueryService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 查询指定租户的所有流程
     * 企业场景:SaaS平台中,每个企业客户只能看到自己的流程
     */
    fun getProcessesForTenant(tenantId: String): List<Map<String, Any>> {
        val processes = repositoryService.createProcessDefinitionQuery()
            .processDefinitionTenantId(tenantId)
            .latestVersion()
            .orderByProcessDefinitionName()
            .asc()
            .list()
        
        return processes.map { pd ->
            mapOf(
                "processKey" to pd.key,
                "processName" to pd.name,
                "version" to pd.version,
                "category" to pd.category,
                "tenantId" to pd.tenantId,
                "status" to if (pd.isSuspended) "已停用" else "运行中"
            )
        }
    }
    
    /**
     * 统计租户的流程数量
     */
    fun countProcessesForTenant(tenantId: String): Long {
        return repositoryService.createProcessDefinitionQuery()
            .processDefinitionTenantId(tenantId)
            .latestVersion()
            .count()
    }
}

示例5:分页查询流程定义

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

data class PageResult<T>(
    val items: List<T>,
    val total: Long,
    val pageNo: Int,
    val pageSize: Int
)

@Service
class ProcessDefinitionPageService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 分页查询流程定义
     * 企业场景:流程管理后台支持分页展示,提升大量流程时的性能
     */
    fun getProcessDefinitionsPage(
        pageNo: Int,
        pageSize: Int,
        nameFilter: String? = null,
        category: String? = null
    ): PageResult<Map<String, Any>> {
        
        val query = repositoryService.createProcessDefinitionQuery()
            .latestVersion()
        
        // 添加可选的查询条件
        nameFilter?.let { query.processDefinitionNameLike("%$it%") }
        category?.let { query.processDefinitionCategory(it) }
        
        // 获取总数
        val total = query.count()
        
        // 分页查询
        val processes = query
            .orderByProcessDefinitionName()
            .asc()
            .listPage((pageNo - 1) * pageSize, pageSize)
        
        val items = processes.map { pd ->
            mapOf(
                "id" to pd.id,
                "key" to pd.key,
                "name" to pd.name,
                "version" to pd.version,
                "category" to pd.category,
                "isSuspended" to pd.isSuspended
            )
        }
        
        return PageResult(
            items = items,
            total = total,
            pageNo = pageNo,
            pageSize = pageSize
        )
    }
}

示例6:查询特定流程的所有版本

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

data class ProcessVersionHistory(
    val processKey: String,
    val processName: String,
    val totalVersions: Int,
    val versions: List<VersionInfo>
)

data class VersionInfo(
    val version: Int,
    val deploymentId: String,
    val deploymentTime: String,
    val isSuspended: Boolean,
    val isCurrent: Boolean
)

@Service
class ProcessVersionService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 查询流程的所有历史版本
     * 企业场景:流程版本管理,查看流程的演进历史
     */
    fun getProcessVersionHistory(processKey: String): ProcessVersionHistory {
        // 查询该流程的所有版本
        val allVersions = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(processKey)
            .orderByProcessDefinitionVersion()
            .desc()
            .list()
        
        if (allVersions.isEmpty()) {
            throw IllegalArgumentException("流程 $processKey 不存在")
        }
        
        val latestVersion = allVersions.first()
        
        val versions = allVersions.map { pd ->
            VersionInfo(
                version = pd.version,
                deploymentId = pd.deploymentId,
                deploymentTime = pd.deploymentId, // 简化示例,实际需要从Deployment获取时间
                isSuspended = pd.isSuspended,
                isCurrent = pd.version == latestVersion.version
            )
        }
        
        return ProcessVersionHistory(
            processKey = processKey,
            processName = latestVersion.name,
            totalVersions = allVersions.size,
            versions = versions
        )
    }
}

示例7:高级条件组合查询

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service

data class ProcessSearchCriteria(
    val nameKeyword: String? = null,
    val category: String? = null,
    val isActive: Boolean? = null,
    val tenantId: String? = null,
    val hasStartFormKey: Boolean? = null
)

@Service
class AdvancedProcessQueryService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 高级条件组合查询
     * 企业场景:流程搜索功能,支持多条件组合筛选
     */
    fun searchProcesses(criteria: ProcessSearchCriteria): List<Map<String, Any>> {
        val query = repositoryService.createProcessDefinitionQuery()
        
        // 动态添加查询条件
        criteria.nameKeyword?.let {
            query.processDefinitionNameLike("%$it%")
        }
        
        criteria.category?.let {
            query.processDefinitionCategory(it)
        }
        
        criteria.isActive?.let { isActive ->
            if (isActive) {
                query.active()
            } else {
                query.suspended()
            }
        }
        
        criteria.tenantId?.let {
            query.processDefinitionTenantId(it)
        }
        
        criteria.hasStartFormKey?.let { hasForm ->
            if (hasForm) {
                query.processDefinitionWithFormKey()
            }
        }
        
        // 只返回最新版本
        val processes = query.latestVersion()
            .orderByProcessDefinitionName()
            .asc()
            .list()
        
        return processes.map { pd ->
            mapOf(
                "id" to pd.id,
                "key" to pd.key,
                "name" to pd.name,
                "version" to pd.version,
                "category" to pd.category,
                "tenantId" to pd.tenantId,
                "isActive" to !pd.isSuspended,
                "hasStartForm" to pd.hasStartFormKey()
            )
        }
    }
}

示例8:流程定义管理REST API

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/api/processes")
class ProcessDefinitionRestController(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 查询流程列表(支持分页和筛选)
     * 企业场景:前端流程管理页面调用
     */
    @GetMapping
    fun listProcesses(
        @RequestParam(required = false) name: String?,
        @RequestParam(required = false) category: String?,
        @RequestParam(defaultValue = "1") page: Int,
        @RequestParam(defaultValue = "10") size: Int
    ): Map<String, Any> {
        
        val query = repositoryService.createProcessDefinitionQuery()
            .latestVersion()
        
        name?.let { query.processDefinitionNameLike("%$it%") }
        category?.let { query.processDefinitionCategory(it) }
        
        val total = query.count()
        val processes = query
            .orderByProcessDefinitionName()
            .asc()
            .listPage((page - 1) * size, size)
        
        return mapOf(
            "data" to processes.map { pd ->
                mapOf(
                    "id" to pd.id,
                    "key" to pd.key,
                    "name" to pd.name,
                    "version" to pd.version,
                    "category" to pd.category,
                    "status" to if (pd.isSuspended) "停用" else "运行中"
                )
            },
            "total" to total,
            "page" to page,
            "size" to size
        )
    }
    
    /**
     * 获取流程的所有版本
     */
    @GetMapping("/{processKey}/versions")
    fun getProcessVersions(@PathVariable processKey: String): List<Map<String, Any>> {
        val versions = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(processKey)
            .orderByProcessDefinitionVersion()
            .desc()
            .list()
        
        return versions.map { pd ->
            mapOf(
                "version" to pd.version,
                "id" to pd.id,
                "deploymentId" to pd.deploymentId,
                "isSuspended" to pd.isSuspended
            )
        }
    }
    
    /**
     * 按类别统计流程数量
     */
    @GetMapping("/statistics/by-category")
    fun countByCategory(): List<Map<String, Any>> {
        val categories = listOf("HR", "Finance", "Procurement", "Contract")
        
        return categories.map { category ->
            val count = repositoryService.createProcessDefinitionQuery()
                .processDefinitionCategory(category)
                .latestVersion()
                .count()
            
            mapOf(
                "category" to category,
                "count" to count
            )
        }
    }
}

注意事项

1. latestVersion() 的使用

  • 在大多数业务场景中,应使用 latestVersion() 只查询最新版本
  • 避免返回同一流程的多个历史版本,造成用户困惑

2. 性能优化

  • 使用 count() 获取总数,避免加载所有数据再计数
  • 大数据量场景必须使用 listPage() 分页查询
  • 合理使用查询条件,避免全表扫描

3. 多租户场景

  • SaaS应用必须添加 processDefinitionTenantId() 过滤
  • 防止租户数据泄露

4. 挂起状态过滤

  • 使用 active() 只查询未挂起的流程
  • 使用 suspended() 只查询已挂起的流程
  • 默认不过滤,会返回所有状态的流程

5. 排序建议

  • 推荐使用 orderByProcessDefinitionName() 按名称排序,用户体验更好
  • 也可使用 orderByProcessDefinitionKey()orderByDeploymentId()

6. 结果处理

  • list() 返回所有结果,适用于数据量小的场景
  • listPage(offset, limit) 分页返回,适用于数据量大的场景
  • singleResult() 返回唯一结果,适用于明确只有一个结果的场景
  • count() 返回结果数量,不加载实体数据

相关 API

  • RepositoryService.createProcessDefinitionQuery() - 创建查询
  • RepositoryService.getProcessDefinition() - 根据ID获取流程定义
  • RepositoryService.createDeploymentQuery() - 查询部署
  • RepositoryService.createModelQuery() - 查询流程模型

常用查询条件速查

方法说明使用场景
processDefinitionKey(String key)按流程Key查询查询特定流程
processDefinitionName(String name)按流程名称精确查询精确匹配
processDefinitionNameLike(String pattern)按流程名称模糊查询搜索功能
processDefinitionCategory(String category)按类别查询分类管理
processDefinitionTenantId(String tenantId)按租户ID查询多租户隔离
latestVersion()只返回最新版本大多数场景
processDefinitionVersion(Integer version)查询特定版本版本管理
active()只查询未挂起的流程可用流程列表
suspended()只查询已挂起的流程停用流程管理
processDefinitionWithFormKey()只查询有启动表单的流程表单流程筛选

最佳实践

1. 封装通用查询服务

kotlin
@Service
class ProcessQueryFacade(
    private val repositoryService: RepositoryService
) {
    
    fun getActiveProcesses(tenantId: String? = null): List<ProcessDefinition> {
        val query = repositoryService.createProcessDefinitionQuery()
            .latestVersion()
            .active()
        
        tenantId?.let { query.processDefinitionTenantId(it) }
        
        return query.orderByProcessDefinitionName().asc().list()
    }
}

2. 缓存查询结果

kotlin
@Service
class CachedProcessQueryService(
    private val repositoryService: RepositoryService
) {
    
    @Cacheable("processDefinitions", key = "#tenantId")
    fun getProcessDefinitionsForTenant(tenantId: String): List<ProcessDefinition> {
        return repositoryService.createProcessDefinitionQuery()
            .processDefinitionTenantId(tenantId)
            .latestVersion()
            .list()
    }
}

本文档说明

  • 基于 Flowable 7.1.0 版本编写
  • 所有示例均可直接在 Spring Boot + Kotlin 项目中使用
  • 示例场景来自真实企业应用,具有实际参考价值