BPMN-Activiti-简单流程委托

流程执行顺序和所需委托列表

根据你提供的BPMN流程定义,以下是完整的执行顺序和所需的委托组件:

流程执行顺序

scss 复制代码
开始(start)
↓
apply_params (应用参数)
↓
init_rag (初始化RAG)
↓
chat (聊天处理)
↓
[等待 chat_complete 信号]
↓
save_chat_record (保存聊天记录)
↓
end_chat (结束聊天)
↓
结束(end)

所需委托组件列表

1. apply_params - 参数应用

java 复制代码
@Component("apply_params")
public class ApplyParamsDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 处理输入参数,设置流程变量
        // 例如:验证参数、设置默认值、初始化上下文等
    }
}

2. init_rag - 初始化RAG

java 复制代码
@Component("init_rag")
public class InitRagDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 初始化RAG(检索增强生成)系统
        // 例如:加载知识库、建立索引、初始化向量数据库等
    }
}

3. chat - 聊天处理

java 复制代码
@Component("chat")
public class ChatDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 执行聊天逻辑
        // 例如:调用AI模型、处理用户消息、生成回复等
        // 完成后需要外部触发 chat_complete 信号
    }
}

4. save_chat_record - 保存聊天记录

java 复制代码
@Component("save_chat_record")
public class SaveChatRecordDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 保存聊天记录到数据库
        // 例如:存储对话历史、用户消息、AI回复等
    }
}

5. end_chat - 结束聊天

java 复制代码
@Component("end_chat")
public class EndChatDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 执行结束聊天的清理工作
        // 例如:释放资源、更新会话状态、生成摘要等
    }
}

完整的实现示例

java 复制代码
// 1. 参数应用委托
@Component("apply_params")
public class ApplyParamsDelegate implements JavaDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(ApplyParamsDelegate.class);
    
    @Override
    public void execute(DelegateExecution execution) {
        logger.info("=== 执行参数应用 ===");
        
        // 获取输入参数
        String userId = (String) execution.getVariable("userId");
        String userMessage = (String) execution.getVariable("userMessage");
        Map<String, Object> config = (Map<String, Object>) execution.getVariable("config");
        
        // 参数验证和处理
        Map<String, Object> processedParams = new HashMap<>();
        processedParams.put("userId", userId);
        processedParams.put("timestamp", new Date());
        processedParams.put("messageLength", userMessage != null ? userMessage.length() : 0);
        
        // 设置默认配置
        if (config == null) {
            config = new HashMap<>();
            config.put("maxTokens", 1000);
            config.put("temperature", 0.7);
        }
        processedParams.put("config", config);
        
        // 设置流程变量
        execution.setVariable("processedParams", processedParams);
        execution.setVariable("status", "PARAMS_APPLIED");
        
        logger.info("参数应用完成: {}", processedParams);
    }
}
java 复制代码
// 2. RAG初始化委托
@Component("init_rag")
public class InitRagDelegate implements JavaDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(InitRagDelegate.class);
    
    @Autowired
    private KnowledgeBaseService knowledgeBaseService;
    
    @Override
    public void execute(DelegateExecution execution) {
        logger.info("=== 初始化RAG系统 ===");
        
        Map<String, Object> processedParams = (Map<String, Object>) execution.getVariable("processedParams");
        String userId = (String) processedParams.get("userId");
        
        try {
            // 初始化知识库
            RagContext ragContext = knowledgeBaseService.initializeForUser(userId);
            
            // 设置RAG上下文
            execution.setVariable("ragContext", ragContext);
            execution.setVariable("ragStatus", "INITIALIZED");
            
            logger.info("RAG初始化完成,用户: {}", userId);
            
        } catch (Exception e) {
            logger.error("RAG初始化失败", e);
            execution.setVariable("ragStatus", "FAILED");
            execution.setVariable("error", e.getMessage());
        }
    }
}
java 复制代码
// 3. 聊天处理委托
@Component("chat")
public class ChatDelegate implements JavaDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(ChatDelegate.class);
    
    @Autowired
    private ChatService chatService;
    
    @Override
    public void execute(DelegateExecution execution) {
        logger.info("=== 执行聊天处理 ===");
        
        String userMessage = (String) execution.getVariable("userMessage");
        Map<String, Object> processedParams = (Map<String, Object>) execution.getVariable("processedParams");
        RagContext ragContext = (RagContext) execution.getVariable("ragContext");
        
        try {
            // 执行聊天处理
            ChatRequest request = new ChatRequest(userMessage, ragContext, processedParams);
            ChatResponse response = chatService.processChat(request);
            
            // 设置聊天结果
            execution.setVariable("chatResponse", response);
            execution.setVariable("chatStatus", "PROCESSED");
            
            logger.info("聊天处理完成,用户消息: {}", userMessage);
            logger.info("AI回复: {}", response.getReply());
            
        } catch (Exception e) {
            logger.error("聊天处理失败", e);
            execution.setVariable("chatStatus", "FAILED");
            execution.setVariable("error", e.getMessage());
        }
        
        // 注意:这里不会自动触发 chat_complete 信号
        // 需要外部系统在聊天真正完成后手动触发信号
    }
}
java 复制代码
// 4. 保存聊天记录委托
@Component("save_chat_record")
public class SaveChatRecordDelegate implements JavaDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(SaveChatRecordDelegate.class);
    
    @Autowired
    private ChatRecordRepository chatRecordRepository;
    
    @Override
    public void execute(DelegateExecution execution) {
        logger.info("=== 保存聊天记录 ===");
        
        String processInstanceId = execution.getProcessInstanceId();
        String userId = (String) execution.getVariable("userId");
        String userMessage = (String) execution.getVariable("userMessage");
        ChatResponse chatResponse = (ChatResponse) execution.getVariable("chatResponse");
        Map<String, Object> processedParams = (Map<String, Object>) execution.getVariable("processedParams");
        
        try {
            // 构建聊天记录
            ChatRecord record = new ChatRecord();
            record.setProcessInstanceId(processInstanceId);
            record.setUserId(userId);
            record.setUserMessage(userMessage);
            record.setAiReply(chatResponse != null ? chatResponse.getReply() : null);
            record.setTimestamp(new Date());
            record.setParams(processedParams);
            
            // 保存到数据库
            chatRecordRepository.save(record);
            
            execution.setVariable("savedRecordId", record.getId());
            execution.setVariable("saveStatus", "SUCCESS");
            
            logger.info("聊天记录保存成功,记录ID: {}", record.getId());
            
        } catch (Exception e) {
            logger.error("保存聊天记录失败", e);
            execution.setVariable("saveStatus", "FAILED");
            execution.setVariable("error", e.getMessage());
        }
    }
}
java 复制代码
// 5. 结束聊天委托
@Component("end_chat")
public class EndChatDelegate implements JavaDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(EndChatDelegate.class);
    
    @Override
    public void execute(DelegateExecution execution) {
        logger.info("=== 结束聊天会话 ===");
        
        String processInstanceId = execution.getProcessInstanceId();
        String userId = (String) execution.getVariable("userId");
        
        // 执行清理工作
        execution.setVariable("endTime", new Date());
        execution.setVariable("finalStatus", "COMPLETED");
        
        // 记录完成日志
        logger.info("聊天会话完成 - 流程实例: {}, 用户: {}", processInstanceId, userId);
        
        // 可以在这里添加:
        // - 资源清理
        // - 会话统计
        // - 通知其他系统
        // - 生成会话报告等
    }
}

信号触发服务

java 复制代码
@Component
public class SignalService {
    
    @Autowired
    private RuntimeService runtimeService;
    
    /**
     * 触发聊天完成信号
     */
    public void triggerChatComplete(String processInstanceId) {
        runtimeService.signalEventReceived("chat_complete", processInstanceId);
    }
}

流程启动示例

java 复制代码
@RestController
public class ChatController {
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private SignalService signalService;
    
    @PostMapping("/chat")
    public ResponseEntity<?> startChat(@RequestBody ChatRequestDto request) {
        
        // 设置流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("userId", request.getUserId());
        variables.put("userMessage", request.getMessage());
        variables.put("config", request.getConfig());
        
        // 启动流程
        ProcessInstance processInstance = runtimeService
            .startProcessInstanceByKey("chat_default", variables);
        
        // 流程会自动执行到 chat 任务
        // 当 chat 任务真正完成后,需要手动触发信号
        
        return ResponseEntity.ok(Map.of(
            "processInstanceId", processInstance.getId(),
            "status", "STARTED"
        ));
    }
    
    /**
     * 当聊天真正完成后调用此接口触发信号
     */
    @PostMapping("/chat/complete/{processInstanceId}")
    public ResponseEntity<?> completeChat(@PathVariable String processInstanceId) {
        signalService.triggerChatComplete(processInstanceId);
        return ResponseEntity.ok(Map.of("status", "SIGNAL_SENT"));
    }
}

总结

这个流程需要以下5个委托组件:

  1. apply_params - 参数预处理
  2. init_rag - RAG系统初始化
  3. chat - 核心聊天处理
  4. save_chat_record - 数据持久化
  5. end_chat - 会话结束处理

关键点

  • chat 任务完成后需要外部系统手动触发 chat_complete 信号
  • 流程是线性执行的,没有分支路径
  • 所有服务任务都通过委托表达式调用Spring Bean
相关推荐
天若有情67314 小时前
新闻通稿 | 软件产业迈入“智能重构”新纪元:自主进化、人机共生与责任挑战并存
服务器·前端·后端·重构·开发·资讯·新闻
清水15 小时前
Spring Boot企业级开发入门
java·spring boot·后端
星释16 小时前
Rust 练习册 :Proverb与字符串处理
开发语言·后端·rust
ZZHHWW17 小时前
RocketMQ vs Kafka01 - 存储架构深度对比
后端
依_旧17 小时前
MySQL下载安装配置(超级超级入门级)
java·后端
熊小猿17 小时前
RabbitMQ死信交换机与延迟队列:原理、实现与最佳实践
开发语言·后端·ruby
淘源码d17 小时前
什么是医院随访系统?成熟在用的智慧随访系统源码
java·spring boot·后端·开源·源码·随访系统·随访系统框架
武子康18 小时前
大数据-147 Java 访问 Apache Kudu:从建表到 CRUD(含 KuduSession 刷新模式与多 Master 配置)
大数据·后端·nosql
2301_7951672018 小时前
玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
开发语言·后端·算法·安全·rust
程序猿阿越18 小时前
Kafka源码(七)事务消息
java·后端·源码阅读