Skip to content

Commit

Permalink
feat(backend): 提单通知优化改造 #5442
Browse files Browse the repository at this point in the history
  • Loading branch information
iSecloud authored and zhangzhw8 committed Jul 9, 2024
1 parent 23e3a1c commit 58097c7
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 53 deletions.
46 changes: 12 additions & 34 deletions dbm-ui/backend/flow/signal/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@
"""
import logging

from celery import current_app
from django.utils import timezone
from django.utils.translation import ugettext as _

from backend.components.cmsi.handler import CmsiHandler
from backend.db_dirty.handlers import DBDirtyMachineHandler
from backend.flow.consts import StateType
from backend.flow.engine.bamboo.engine import BambooEngine
from backend.flow.models import FlowNode, FlowTree
from backend.ticket.constants import FlowCallbackType, FlowType, TicketFlowStatus
from backend.ticket.constants import FlowCallbackType, FlowMsgType, FlowType, TicketFlowStatus
from backend.ticket.flow_manager.inner import InnerFlow
from backend.ticket.flow_manager.manager import TicketFlowManager
from backend.ticket.models import Flow, Ticket
from backend.ticket.models import Ticket
from backend.ticket.tasks.ticket_tasks import send_msg_for_flow

logger = logging.getLogger("flow")

Expand Down Expand Up @@ -95,7 +94,15 @@ def callback_ticket(ticket_id, root_id):

# 在认为inner flow执行结束情况下,执行inner flow的后继动作
if inner_flow_obj.status not in [TicketFlowStatus.PENDING, TicketFlowStatus.RUNNING]:
send_msg_for_flow.apply_async(args=[current_flow.id])
send_msg_for_flow.apply_async(
kwargs={
"flow_id": current_flow.id,
"flow_msg_type": FlowMsgType.DONE.value,
"flow_status": current_flow.status,
"processor": ticket.creator,
"receiver": ticket.creator,
}
)
inner_flow_obj.callback(callback_type=FlowCallbackType.POST_CALLBACK.value)

# 如果flow type的类型为快速任务,则跳过callback
Expand All @@ -105,32 +112,3 @@ def callback_ticket(ticket_id, root_id):
if current_flow and current_flow.flow_obj_id == root_id:
manager = TicketFlowManager(ticket=ticket)
manager.run_next_flow()


@current_app.task(ignore_result=True)
def send_msg_for_flow(flow_id: int):
"""
发送消息
"""
flow = Flow.objects.get(id=flow_id)
inner_flow_obj = InnerFlow(flow_obj=flow)
ticket = flow.ticket
ticket_type = ticket.get_ticket_type_display()

msg = ticket.send_msg_config or {}
msg.update(
{
"receiver__username": msg.get("receiver__username") or ticket.creator,
"title": _("DBM数据库管理 {ticket_type} 执行结果").format(ticket_type=ticket_type),
"content": _(
"{ticket_type} {flow_alias} 执行{flow_status}。\n" "单据详情:{ticket_url}\n" "任务详情:{flow_url}\n"
).format(
ticket_type=ticket_type,
flow_alias=flow.flow_alias,
flow_status=flow.get_status_display(),
ticket_url=ticket.url,
flow_url=inner_flow_obj.url,
),
}
)
CmsiHandler.send_msg(msg)
12 changes: 12 additions & 0 deletions dbm-ui/backend/ticket/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,3 +607,15 @@ class OperateNodeActionType(str, StructuredEnum):
class ItsmTicketNodeEnum(str, StructuredEnum):
ApprovalOption = EnumField("审批意见", "审批意见")
Remark = EnumField("备注", "备注")


class FlowMsgType(str, StructuredEnum):
DONE = EnumField(_("完成"), _("完成"))
TODO = EnumField(_("代办"), _("代办"))
PENDING = EnumField(_("待审批"), _("待审批"))


class FlowMsgStatus(str, StructuredEnum):
DONE = EnumField(_("完成"), _("完成"))
UNCONFIRMED = EnumField(_("待确认"), _("待确认"))
PENDING = EnumField(_("待审批"), _("待审批"))
14 changes: 13 additions & 1 deletion dbm-ui/backend/ticket/flow_manager/itsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@

from backend.components import ItsmApi
from backend.components.itsm.constants import ItsmTicketStatus
from backend.ticket.constants import TicketFlowStatus, TicketStatus
from backend.ticket.constants import FlowMsgStatus, FlowMsgType, TicketFlowStatus, TicketStatus
from backend.ticket.flow_manager.base import BaseTicketFlow
from backend.ticket.models import Flow
from backend.ticket.tasks.ticket_tasks import send_msg_for_flow
from backend.utils.time import datetime2str, standardized_time_str


Expand Down Expand Up @@ -98,4 +99,15 @@ def _url(self) -> str:

def _run(self) -> str:
data = ItsmApi.create_ticket(self.flow_obj.details)
# 异步发送待审批消息
itsm_fields = {f["key"]: f["value"] for f in self.flow_obj.details["fields"]}
send_msg_for_flow.apply_async(
kwargs={
"flow_id": self.flow_obj.id,
"flow_msg_type": FlowMsgType.PENDING.value,
"flow_status": FlowMsgStatus.PENDING.value,
"processor": itsm_fields["approver"],
"receiver": self.ticket.creator,
}
)
return data["sn"]
25 changes: 10 additions & 15 deletions dbm-ui/backend/ticket/models/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from backend import env
from backend.bk_web.constants import LEN_MIDDLE, LEN_SHORT
from backend.bk_web.models import AuditedModel
from backend.components.cmsi.handler import CmsiHandler
from backend.ticket.constants import TicketFlowStatus, TodoStatus, TodoType
from backend.ticket.constants import FlowMsgStatus, FlowMsgType, TicketFlowStatus, TodoStatus, TodoType
from backend.ticket.tasks.ticket_tasks import send_msg_for_flow

logger = logging.getLogger("root")

Expand All @@ -29,21 +29,16 @@ def exist_unfinished(self):

def create(self, **kwargs):
todo = super().create(**kwargs)
ticket = todo.ticket
ticket_type = ticket.get_ticket_type_display()

msg = ticket.send_msg_config or {}
msg.update(
{
"receiver__username": ",".join(todo.operators),
"title": _("DBM数据库管理 待办通知").format(ticket_type=ticket_type),
"content": _("有一条[{ticket_type}]待办需要您处理\n" "待办详情:{todo_url}\n").format(
ticket_type=ticket_type,
todo_url=todo.url,
),
send_msg_for_flow.apply_async(
kwargs={
"flow_id": todo.flow.id,
"flow_msg_type": FlowMsgType.TODO.value,
"flow_status": FlowMsgStatus.UNCONFIRMED.value,
"processor": todo.operators,
"receiver": todo.creator,
"detail_address": todo.url,
}
)
CmsiHandler.send_msg(msg)

return todo

Expand Down
74 changes: 71 additions & 3 deletions dbm-ui/backend/ticket/tasks/ticket_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@
from django.utils.translation import ugettext_lazy as _

from backend import env
from backend.components import BKLogApi
from backend.components import BKLogApi, ItsmApi
from backend.components.cmsi.handler import CmsiHandler
from backend.db_meta.enums import ClusterType, InstanceInnerRole
from backend.db_meta.models import Cluster, StorageInstance
from backend.db_meta.models import AppCache, Cluster, StorageInstance
from backend.ticket.builders.common.constants import MYSQL_CHECKSUM_TABLE, MySQLDataRepairTriggerMode
from backend.ticket.constants import FlowErrCode, TicketType
from backend.ticket.constants import FlowErrCode, FlowType, TicketType
from backend.ticket.exceptions import TicketTaskTriggerException
from backend.ticket.flow_manager.inner import InnerFlow
from backend.ticket.models.ticket import Flow, Ticket
Expand Down Expand Up @@ -239,3 +240,70 @@ def apply_ticket_task(
raise TicketTaskTriggerException(_("不支持的定时类型: {}").format(eta))

return res


@shared_task
def send_msg_for_flow(
flow_id: int,
flow_msg_type: str,
flow_status: str,
processor: str,
receiver: str = "",
detail_address: str = None,
):
"""
异步发送消息通知
@param flow_id: 流程ID
@param flow_msg_type: 流程类型
@param flow_status: 流程状态
@param receiver: 通知人(多个处理人用,分割)
@param processor: 处理人(多个处理人用,分割)
@param detail_address: 查看详情链接
"""
flow = Flow.objects.get(id=flow_id)
ticket = flow.ticket
receiver = receiver or ticket.creator
ticket_type = ticket.get_ticket_type_display()
biz_name = AppCache.get_biz_name(ticket.bk_biz_id)

# 通知模板
content = _(
"""
单据类型:{ticket_type}
所属业务:{biz_name}
提单人:{creator}
提单时间:{submit_time}
处理人:{processor}
执行情况:{flow_status}
查看详情:{detail_address}
"""
).format(
ticket_type=ticket_type,
biz_name=biz_name,
creator=ticket.creator,
submit_time=ticket.create_at.astimezone(),
processor=processor,
flow_status=flow_status,
detail_address=detail_address or ticket.url,
)

if flow.flow_type == FlowType.BK_ITSM.value:
# 调用ITSM接口查询审批状态
data = ItsmApi.ticket_approval_result({"sn": [flow.flow_obj_id]}, use_admin=True)
try:
approval_address = data[0]["ticket_url"]
except IndexError:
approval_address = ""
content += _("审批链接:{approval_address}").format(approval_address=approval_address)

# 通知人 = 额外通知人 + 处理人 + 提单人
receiver__username = set(f"{receiver},{processor},{ticket.creator}".split(","))
msg = ticket.send_msg_config or {}
msg.update(
{
"receiver__username": ",".join(receiver__username),
"title": _("【数据库管理】 {flow_msg_type}通知").format(flow_msg_type=flow_msg_type),
"content": content,
}
)
CmsiHandler.send_msg(msg)

0 comments on commit 58097c7

Please sign in to comment.