#!/usr/bin/env python # -*- coding: utf-8 -*- """ 通知节点处理器 处理流程中的通知发送 """ import logging from typing import Dict, TYPE_CHECKING from online_dev.workflow.engine.handlers.base_handler import BaseNodeHandler if TYPE_CHECKING: from online_dev.workflow.engine.base import ExecutionContext logger = logging.getLogger(__name__) class NotifyHandler(BaseNodeHandler): """ 通知节点处理器 支持多种通知渠道: - site: 站内信 - email: 邮件 - sms: 短信 - wechat: 微信 - dingtalk: 钉钉 - feishu: 飞书 """ async def execute(self, context: 'ExecutionContext', node: Dict) -> None: """ 执行通知节点:发送通知 """ from online_dev.workflow.engine.assignee_resolver import assignee_resolver node_id = self.get_node_id(node) node_name = self.get_node_name(node) node_config = self.get_node_config(node) # 解析通知对象 recipient_ids = await assignee_resolver.resolve( context.db, { 'assigneeType': node_config.get('recipientType', 'user'), 'assignees': node_config.get('recipients', []), 'assigneeLevel': node_config.get('recipientLevel'), 'assigneeField': node_config.get('recipientField'), 'assigneeFields': node_config.get('recipientFields'), 'assigneeFieldMappings': node_config.get('recipientFieldMappings'), }, context.instance, context.form_data, ) channels = node_config.get('channels', ['site']) title = node_config.get('title', '') content = node_config.get('content', '') logger.info(f"通知节点 - 发送给 {len(recipient_ids)} 人,渠道: {channels}") # 构建模板变量上下文 notify_context = { 'initiator': '', 'title': context.instance.title, 'instance_no': context.instance.instance_no, 'node_name': node_name, 'form': context.form_data, } # 调用通知服务发送 if recipient_ids: from core.message.service import NotifyService await NotifyService.send( db=context.db, recipient_ids=recipient_ids, title=title, content=content, channels=channels, msg_type="workflow", context=notify_context, sender_id=context.instance.initiator_id, ) # 记录通知日志 await self.create_log( context, node, 'notify', comment=f'发送通知: {title}', extra_data={ 'recipients': recipient_ids, 'channels': channels, 'title': title, 'content': content, }, ) logger.info(f"通知发送完成") # 通知发送后继续推进 await self.advance_to_next(context, node)