Skip to content

activateProcessDefinitionByKey

Flowable 7.1.0 摘要:根据流程定义Key激活被挂起的流程定义,激活后可以启动新的流程实例。

方法签名与说明

void activateProcessDefinitionByKey(String processDefinitionKey)

激活指定Key的流程定义的最新版本。激活后,可以启动新的流程实例。

Parameters:

  • processDefinitionKey - 流程定义的Key,不能为null

Throws:

  • FlowableObjectNotFoundException - 当流程定义不存在时

void activateProcessDefinitionByKey(String processDefinitionKey, boolean activateProcessInstances, Date activationDate)

激活指定Key的流程定义,可选择是否同时激活所有被挂起的流程实例,并可指定激活时间。

Parameters:

  • processDefinitionKey - 流程定义的Key
  • activateProcessInstances - 是否同时激活所有流程实例
  • activationDate - 激活生效时间(可为null表示立即生效)

常见使用场景

1. 维护完成后恢复流程

流程维护或升级完成后,重新激活流程,允许启动新实例。

2. 节假日后恢复业务

节假日期间挂起的流程,在工作日开始时自动激活。

3. 紧急修复后恢复服务

发现流程问题紧急挂起后,修复完成立即激活。

Kotlin + Spring Boot 调用示例

示例1:激活流程定义

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

@Service
class ProcessActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 激活流程定义
     * 企业场景:请假流程维护完成,重新开放申请
     */
    fun activateLeaveProcess() {
        repositoryService.activateProcessDefinitionByKey("leave-approval-process")
        println("请假流程已激活,现在可以提交新申请")
    }
}

示例2:激活流程并同时激活所有实例

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

@Service
class FullActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 激活流程及所有实例
     * 企业场景:紧急修复完成,恢复所有暂停的流程
     */
    fun fullActivate(processDefinitionKey: String) {
        repositoryService.activateProcessDefinitionByKey(
            processDefinitionKey,
            true, // 同时激活所有流程实例
            null  // 立即生效
        )
        
        println("流程 $processDefinitionKey 及所有实例已激活")
    }
}

示例3:定时激活流程(节假日后自动激活)

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.stereotype.Service
import java.util.Calendar

@Service
class ScheduledActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 定时激活流程
     * 企业场景:国庆假期结束后自动激活业务流程
     */
    fun scheduleActivationAfterHoliday() {
        // 设置激活时间为10月8日上午9点
        val activationTime = Calendar.getInstance().apply {
            set(2024, Calendar.OCTOBER, 8, 9, 0, 0)
        }.time
        
        listOf(
            "leave-approval-process",
            "expense-approval-process",
            "procurement-process"
        ).forEach { processKey ->
            repositoryService.activateProcessDefinitionByKey(
                processKey,
                true,
                activationTime
            )
            println("$processKey 将在 $activationTime 自动激活")
        }
    }
}

示例4:安全激活(带状态检查)

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

@Service
class SafeActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 安全激活流程(检查当前状态)
     * 企业场景:激活前确认流程确实处于挂起状态
     */
    fun safeActivate(processDefinitionKey: String): Boolean {
        // 获取最新版本的流程定义
        val processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(processDefinitionKey)
            .latestVersion()
            .singleResult()
            ?: return false
        
        if (!processDefinition.isSuspended) {
            println("流程已经是激活状态,无需操作")
            return false
        }
        
        println("流程当前处于挂起状态,开始激活...")
        repositoryService.activateProcessDefinitionByKey(processDefinitionKey)
        println("流程激活成功")
        
        return true
    }
}

示例5:批量激活流程

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

data class ActivationResult(
    val processKey: String,
    val success: Boolean,
    val message: String
)

@Service
class BatchActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 批量激活流程
     * 企业场景:系统维护完成,批量激活所有业务流程
     */
    fun batchActivate(processKeys: List<String>): List<ActivationResult> {
        println("开始批量激活 ${processKeys.size} 个流程...")
        
        return processKeys.map { processKey ->
            try {
                repositoryService.activateProcessDefinitionByKey(processKey)
                
                ActivationResult(
                    processKey = processKey,
                    success = true,
                    message = "激活成功"
                )
            } catch (e: Exception) {
                ActivationResult(
                    processKey = processKey,
                    success = false,
                    message = "激活失败: ${e.message}"
                )
            }
        }
    }
    
    /**
     * 激活所有挂起的流程
     */
    fun activateAllSuspended() {
        val suspendedProcesses = repositoryService.createProcessDefinitionQuery()
            .suspended()
            .latestVersion()
            .list()
        
        val processKeys = suspendedProcesses.map { it.key }.distinct()
        
        println("发现 ${processKeys.size} 个挂起的流程")
        val results = batchActivate(processKeys)
        
        val successCount = results.count { it.success }
        println("激活完成:成功 $successCount 个,失败 ${results.size - successCount} 个")
    }
}

示例6:流程状态管理REST API

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.format.annotation.DateTimeFormat
import org.springframework.web.bind.annotation.*
import java.util.Date

@RestController
@RequestMapping("/api/processes")
class ProcessStateController(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 激活流程定义
     */
    @PostMapping("/{processKey}/activate")
    fun activateProcess(
        @PathVariable processKey: String,
        @RequestParam(defaultValue = "false") activateInstances: Boolean,
        @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") 
        activationTime: Date?
    ): Map<String, Any> {
        
        return try {
            repositoryService.activateProcessDefinitionByKey(
                processKey,
                activateInstances,
                activationTime
            )
            
            mapOf(
                "success" to true,
                "message" to if (activationTime != null) {
                    "流程将在 $activationTime 激活"
                } else {
                    "流程已激活"
                },
                "processKey" to processKey,
                "instancesActivated" to activateInstances
            )
        } catch (e: Exception) {
            mapOf(
                "success" to false,
                "message" to "激活失败: ${e.message}"
            )
        }
    }
    
    /**
     * 检查流程状态
     */
    @GetMapping("/{processKey}/status")
    fun getProcessStatus(@PathVariable processKey: String): Map<String, Any> {
        val processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(processKey)
            .latestVersion()
            .singleResult()
            ?: throw IllegalArgumentException("流程不存在")
        
        return mapOf(
            "processKey" to processKey,
            "processName" to processDefinition.name,
            "version" to processDefinition.version,
            "status" to if (processDefinition.isSuspended) "挂起" else "激活",
            "canStartNewInstance" to !processDefinition.isSuspended
        )
    }
}

示例7:定时任务自动激活

kotlin
import org.flowable.engine.RepositoryService
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service

@Service
class AutoActivationService(
    private val repositoryService: RepositoryService
) {
    
    /**
     * 每周一早上8点自动激活周末挂起的流程
     * 企业场景:某些流程周末不处理,周一自动恢复
     */
    @Scheduled(cron = "0 0 8 * * MON")
    fun activateProcessesOnMonday() {
        val processesToActivate = listOf(
            "contract-approval-process",
            "procurement-approval-process"
        )
        
        println("周一自动激活流程...")
        
        processesToActivate.forEach { processKey ->
            try {
                repositoryService.activateProcessDefinitionByKey(processKey)
                println("$processKey 已激活")
            } catch (e: Exception) {
                println("$processKey 激活失败: ${e.message}")
            }
        }
    }
}

注意事项

1. 状态检查

  • 激活前确认流程确实处于挂起状态
  • 重复激活已激活的流程不会报错,但是无意义的操作

2. 实例激活

  • 使用 activateProcessInstances=true 会激活所有被挂起的实例
  • 谨慎使用,确保业务逻辑允许继续执行

3. 定时激活

  • 定时激活适用于可预见的维护窗口
  • 确保激活时间设置正确

4. 权限控制

  • 激活流程是重要操作,应严格控制权限
  • 建议记录操作日志

5. 通知机制

  • 激活前应通知相关人员
  • 特别是激活实例时,可能影响正在等待的任务

相关 API

  • RepositoryService.activateProcessDefinitionByKey() - 激活流程定义
  • RepositoryService.suspendProcessDefinitionByKey() - 挂起流程定义
  • RepositoryService.activateProcessDefinitionById() - 按ID激活
  • RepositoryService.isProcessDefinitionSuspended() - 检查是否挂起

最佳实践

1. 成对使用挂起和激活

kotlin
class ProcessMaintenanceService(
    private val repositoryService: RepositoryService
) {
    
    fun performMaintenance(processKey: String, maintenanceWork: () -> Unit) {
        // 挂起流程
        repositoryService.suspendProcessDefinitionByKey(processKey)
        
        try {
            // 执行维护工作
            maintenanceWork()
        } finally {
            // 确保激活流程
            repositoryService.activateProcessDefinitionByKey(processKey)
        }
    }
}

2. 记录状态变更

kotlin
fun activateWithLogging(processKey: String, operator: String, reason: String) {
    logger.info("激活流程: $processKey, 操作人: $operator, 原因: $reason")
    repositoryService.activateProcessDefinitionByKey(processKey)
    // 保存审计日志到数据库
}

3. 发送通知

kotlin
fun activateWithNotification(processKey: String) {
    repositoryService.activateProcessDefinitionByKey(processKey)
    notificationService.send("流程 $processKey 已激活,现可提交新申请")
}

本文档说明

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