R50 通知推送:dispatcher 投递服务、业务事件接入与员工推送开关

这个提交包含在:
2026-04-05 11:21:39 +08:00
父节点 ff0a677bf3
当前提交 47e10e6acc
共修改 24 个文件,包含 1701 行新增和 197 行删除
+47 -32
查看文件
@@ -13,7 +13,7 @@ const {
loadPurchaseRequestErpContext,
} = require("../services/integrations/erpProcurement");
const {
createNotifications,
createNotificationsWithRecords,
resolveRecipientsForAssignee,
} = require("../services/notifications");
const {
@@ -24,9 +24,9 @@ const {
buildWorkflowEntityMeta,
normalizeWorkflowEntityType,
} = require("../services/notifications/workflowCopy");
const { enqueueImNotifications } = require("../services/notifications/imEnqueue");
const { sendNotificationEmailSafe } = require("../services/email");
const { NOTIFICATION_TYPES } = require("../constants/notificationTypes");
const { flushNotificationDispatchTasks } = require("../services/notificationDispatcher");
const {
findActiveDelegationForDelegate,
listActiveDelegationPrincipals,
@@ -577,10 +577,9 @@ function resolveWorkflowOutcomeNotificationType(entityType, outcome) {
async function queueTaskAssignedNotifications({
tx,
config,
logger,
actorId,
emailTasks,
dispatchTasks,
recipientEmployeeIds,
title,
body,
@@ -593,7 +592,7 @@ async function queueTaskAssignedNotifications({
return;
}
await createNotifications(tx, {
const notifications = await createNotificationsWithRecords(tx, {
recipientEmployeeIds: recipients,
type: NOTIFICATION_TYPES.workflowTaskAssigned,
title,
@@ -601,19 +600,14 @@ async function queueTaskAssignedNotifications({
targetType: 'workflow_task',
targetId: taskId,
});
await enqueueImNotifications(tx, {
config,
logger,
recipientEmployeeIds: recipients,
dispatchTasks.push({
notifications,
type: NOTIFICATION_TYPES.workflowTaskAssigned,
title,
body,
targetType: 'workflow_task',
targetId: taskId,
targetPath: `/workflow/tasks/${taskId}`,
entityType,
entityId,
actorId,
});
@@ -628,10 +622,9 @@ async function queueTaskAssignedNotifications({
async function queueWorkflowOutcomeNotifications({
tx,
config,
logger,
actorId,
emailTasks,
dispatchTasks,
workflowInstance,
outcome,
comment = null,
@@ -656,7 +649,7 @@ async function queueWorkflowOutcomeNotifications({
? buildRejectedCopy(entityMeta, comment)
: buildReturnedCopy(entityMeta, comment);
await createNotifications(tx, {
const notifications = await createNotificationsWithRecords(tx, {
recipientEmployeeIds: recipients,
type: notificationType,
title: copy.title,
@@ -664,19 +657,14 @@ async function queueWorkflowOutcomeNotifications({
targetType: entityMeta.targetType,
targetId: workflowInstance.entity_id,
});
await enqueueImNotifications(tx, {
config,
logger,
recipientEmployeeIds: recipients,
dispatchTasks.push({
notifications,
type: notificationType,
title: copy.title,
body: copy.body,
targetType: entityMeta.targetType,
targetId: workflowInstance.entity_id,
targetPath: entityMeta.detailPath,
entityType: normalizedEntityType,
entityId: workflowInstance.entity_id,
actorId,
});
@@ -1355,6 +1343,7 @@ async function workflowRoutes(fastify) {
const taskId = parseTaskId(request.params?.taskId);
let result = null;
const emailTasks = [];
const dispatchTasks = [];
await fastify.prisma.$transaction(async (tx) => {
const task = await lockWorkflowTask(tx, taskId);
@@ -1458,10 +1447,9 @@ async function workflowRoutes(fastify) {
await queueTaskAssignedNotifications({
tx,
config: fastify.config,
logger: fastify.log,
actorId: request.employee.id,
emailTasks,
dispatchTasks,
recipientEmployeeIds: recipients,
title: pendingCopy.title,
body: pendingCopy.body,
@@ -1613,10 +1601,9 @@ async function workflowRoutes(fastify) {
try {
await queueWorkflowOutcomeNotifications({
tx,
config: fastify.config,
logger: fastify.log,
actorId: request.employee.id,
emailTasks,
dispatchTasks,
workflowInstance,
outcome: 'approved',
});
@@ -1647,6 +1634,13 @@ async function workflowRoutes(fastify) {
...task,
});
}
await flushNotificationDispatchTasks({
prisma: fastify.prisma,
config: fastify.config,
logger: fastify.log,
requestId: request.id,
tasks: dispatchTasks,
});
return sendData(reply, request, result);
},
@@ -1662,6 +1656,7 @@ async function workflowRoutes(fastify) {
const comment = parseRequiredComment(request.body);
let result = null;
const emailTasks = [];
const dispatchTasks = [];
await fastify.prisma.$transaction(async (tx) => {
const task = await lockWorkflowTask(tx, taskId);
@@ -1797,10 +1792,9 @@ async function workflowRoutes(fastify) {
try {
await queueWorkflowOutcomeNotifications({
tx,
config: fastify.config,
logger: fastify.log,
actorId: request.employee.id,
emailTasks,
dispatchTasks,
workflowInstance,
outcome: 'rejected',
comment,
@@ -1831,6 +1825,13 @@ async function workflowRoutes(fastify) {
...task,
});
}
await flushNotificationDispatchTasks({
prisma: fastify.prisma,
config: fastify.config,
logger: fastify.log,
requestId: request.id,
tasks: dispatchTasks,
});
return sendData(reply, request, result);
},
@@ -1846,6 +1847,7 @@ async function workflowRoutes(fastify) {
const comment = parseRequiredComment(request.body);
let result = null;
const emailTasks = [];
const dispatchTasks = [];
await fastify.prisma.$transaction(async (tx) => {
const task = await lockWorkflowTask(tx, taskId);
@@ -1981,10 +1983,9 @@ async function workflowRoutes(fastify) {
try {
await queueWorkflowOutcomeNotifications({
tx,
config: fastify.config,
logger: fastify.log,
actorId: request.employee.id,
emailTasks,
dispatchTasks,
workflowInstance,
outcome: 'returned',
comment,
@@ -2015,6 +2016,13 @@ async function workflowRoutes(fastify) {
...task,
});
}
await flushNotificationDispatchTasks({
prisma: fastify.prisma,
config: fastify.config,
logger: fastify.log,
requestId: request.id,
tasks: dispatchTasks,
});
return sendData(reply, request, result);
},
@@ -2030,6 +2038,7 @@ async function workflowRoutes(fastify) {
const { toApproverId, reason } = parseTransferBody(request.body);
let result = null;
const emailTasks = [];
const dispatchTasks = [];
await fastify.prisma.$transaction(async (tx) => {
const task = await lockWorkflowTask(tx, taskId);
@@ -2121,10 +2130,9 @@ async function workflowRoutes(fastify) {
const pendingCopy = buildPendingTaskCopy(entityMeta, { transfer: true });
await queueTaskAssignedNotifications({
tx,
config: fastify.config,
logger: fastify.log,
actorId: request.employee.id,
emailTasks,
dispatchTasks,
recipientEmployeeIds: [toApproverId],
title: pendingCopy.title,
body: pendingCopy.body,
@@ -2160,6 +2168,13 @@ async function workflowRoutes(fastify) {
...task,
});
}
await flushNotificationDispatchTasks({
prisma: fastify.prisma,
config: fastify.config,
logger: fastify.log,
requestId: request.id,
tasks: dispatchTasks,
});
return sendData(reply, request, result);
},