R50 通知推送:dispatcher 投递服务、业务事件接入与员工推送开关
这个提交包含在:
@@ -26,14 +26,14 @@ const {
|
||||
} = require("../services/integrations/erpProcurement");
|
||||
const { reserveBudgetForEntity, releaseReservedBudgetIfAny } = require("../services/purchaseBudget");
|
||||
const { sendNotificationEmailSafe } = require("../services/email");
|
||||
const { createNotifications, resolveRecipientsForAssignee } = require("../services/notifications");
|
||||
const { createNotificationsWithRecords, resolveRecipientsForAssignee } = require("../services/notifications");
|
||||
const {
|
||||
buildPendingTaskCopy,
|
||||
buildWorkflowEntityMeta,
|
||||
} = require("../services/notifications/workflowCopy");
|
||||
const { enqueueImNotifications } = require("../services/notifications/imEnqueue");
|
||||
const { NOTIFICATION_TYPES } = require("../constants/notificationTypes");
|
||||
const { openReadStream, StorageNotFoundError, writeBuffer } = require("../services/storage");
|
||||
const { dispatchNotificationBatch } = require("../services/notificationDispatcher");
|
||||
|
||||
const UUID_SCHEMA = z.string().uuid();
|
||||
const DATE_ONLY_SCHEMA = z.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
||||
@@ -896,8 +896,8 @@ function buildSkippedNotificationResult(reason) {
|
||||
return { skipped: true, reason };
|
||||
}
|
||||
|
||||
function buildSkippedImResult(reason) {
|
||||
return { queued: 0, duplicated: 0, matchedChannels: [], skippedReason: reason };
|
||||
function buildSkippedDispatchResult(reason) {
|
||||
return { deliveredChannels: [], skippedReason: reason, notificationCount: 0, eligibleRecipientCount: 0, matchedChannelCount: 0 };
|
||||
}
|
||||
|
||||
function buildSkippedEmailResult(reason, failed = 0) {
|
||||
@@ -934,8 +934,8 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
actorId,
|
||||
loadSummary = loadPurchaseSubmitSummary,
|
||||
resolveRecipients = resolveRecipientsForAssignee,
|
||||
createAppNotifications = createNotifications,
|
||||
enqueueIm = enqueueImNotifications,
|
||||
createAppNotifications = createNotificationsWithRecords,
|
||||
dispatchNotifications = dispatchNotificationBatch,
|
||||
sendEmailSafe = sendNotificationEmailSafe,
|
||||
}) {
|
||||
let copy = buildPendingTaskCopy(
|
||||
@@ -986,7 +986,7 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
return {
|
||||
recipientEmployeeIds: [],
|
||||
notification: buildSkippedNotificationResult("recipient_resolution_failed"),
|
||||
im: buildSkippedImResult("recipient_resolution_failed"),
|
||||
dispatch: buildSkippedDispatchResult("recipient_resolution_failed"),
|
||||
email: buildSkippedEmailResult("recipient_resolution_failed"),
|
||||
};
|
||||
}
|
||||
@@ -995,14 +995,15 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
return {
|
||||
recipientEmployeeIds: [],
|
||||
notification: buildSkippedNotificationResult("no_recipients"),
|
||||
im: buildSkippedImResult("no_recipients"),
|
||||
dispatch: buildSkippedDispatchResult("no_recipients"),
|
||||
email: buildSkippedEmailResult("no_recipients"),
|
||||
};
|
||||
}
|
||||
|
||||
let notification = buildSkippedNotificationResult("not_attempted");
|
||||
let notificationRecords = [];
|
||||
try {
|
||||
notification = await createAppNotifications(prisma, {
|
||||
notificationRecords = await createAppNotifications(prisma, {
|
||||
recipientEmployeeIds,
|
||||
type: NOTIFICATION_TYPES.workflowTaskAssigned,
|
||||
title,
|
||||
@@ -1010,6 +1011,7 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
targetType: "workflow_task",
|
||||
targetId: workflowTaskId,
|
||||
});
|
||||
notification = { count: notificationRecords.length };
|
||||
} catch (error) {
|
||||
logger?.error?.(
|
||||
{
|
||||
@@ -1024,20 +1026,20 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
notification = buildSkippedNotificationResult("notification_failed");
|
||||
}
|
||||
|
||||
let im = buildSkippedImResult("not_attempted");
|
||||
let dispatch = buildSkippedDispatchResult("not_attempted");
|
||||
try {
|
||||
im = await enqueueIm(prisma, {
|
||||
dispatch = await dispatchNotifications({
|
||||
prisma,
|
||||
config,
|
||||
logger,
|
||||
recipientEmployeeIds,
|
||||
requestId,
|
||||
notifications: notificationRecords,
|
||||
type: NOTIFICATION_TYPES.workflowTaskAssigned,
|
||||
title,
|
||||
body,
|
||||
targetType: "workflow_task",
|
||||
targetId: workflowTaskId,
|
||||
targetPath,
|
||||
entityType: "purchase_request",
|
||||
entityId: purchaseRequestId,
|
||||
actorId,
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -1049,9 +1051,9 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
workflowTaskId,
|
||||
recipients: recipientEmployeeIds.length,
|
||||
},
|
||||
"Failed to enqueue purchase submit IM notifications",
|
||||
"Failed to dispatch purchase submit notifications",
|
||||
);
|
||||
im = buildSkippedImResult("enqueue_im_failed");
|
||||
dispatch = buildSkippedDispatchResult("dispatch_failed");
|
||||
}
|
||||
|
||||
let email = buildSkippedEmailResult("not_attempted");
|
||||
@@ -1085,7 +1087,7 @@ async function finalizePurchaseSubmitSideEffects({
|
||||
return {
|
||||
recipientEmployeeIds,
|
||||
notification,
|
||||
im,
|
||||
dispatch,
|
||||
email,
|
||||
};
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户