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

这个提交包含在:
2026-04-05 11:21:39 +08:00
父节点 ff0a677bf3
当前提交 47e10e6acc
共修改 24 个文件,包含 1701 行新增和 197 行删除
@@ -0,0 +1,38 @@
const { signPayload } = require('../../utils/signedUrl');
function resolveBaseUrl(config) {
const origin = String(config?.appOrigin ?? '').split(',')[0]?.trim?.() ?? '';
return origin ? origin.replace(/\/+$/, '') : '';
}
function buildDetailUrl(config, targetPath) {
const path = String(targetPath ?? '').trim();
if (!path) {
return null;
}
const baseUrl = resolveBaseUrl(config);
if (!baseUrl) {
return null;
}
if (path.startsWith('http://') || path.startsWith('https://')) {
return path;
}
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
const token = signPayload(
{
targetPath: normalizedPath,
exp: Math.floor(Date.now() / 1000) + 15 * 60,
},
config.jwtSecret,
);
return `${baseUrl}/api/auth/deeplink?token=${encodeURIComponent(token)}`;
}
module.exports = {
buildDetailUrl,
resolveBaseUrl,
};
+1 -33
查看文件
@@ -7,44 +7,12 @@ const {
matchesNotificationChannel,
normalizeChannelType,
} = require('./imRouting');
const { signPayload } = require('../../utils/signedUrl');
const { buildDetailUrl } = require('./detailUrl');
function uniq(values) {
return Array.from(new Set((values ?? []).filter(Boolean)));
}
function resolveBaseUrl(config) {
const origin = String(config?.appOrigin ?? '').split(',')[0]?.trim?.() ?? '';
return origin ? origin.replace(/\/+$/, '') : '';
}
function buildDetailUrl(config, targetPath) {
const path = String(targetPath ?? '').trim();
if (!path) {
return null;
}
const baseUrl = resolveBaseUrl(config);
if (!baseUrl) {
return null;
}
if (path.startsWith('http://') || path.startsWith('https://')) {
return path;
}
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
const token = signPayload(
{
targetPath: normalizedPath,
exp: Math.floor(Date.now() / 1000) + 15 * 60,
},
config.jwtSecret,
);
return `${baseUrl}/api/auth/deeplink?token=${encodeURIComponent(token)}`;
}
async function resolveRecipientRoleCodes(tx, recipientEmployeeIds) {
const recipientIds = uniq(recipientEmployeeIds);
if (!recipientIds.length) {
+31 -1
查看文件
@@ -49,8 +49,38 @@ async function createNotifications(tx, input) {
});
}
async function createNotificationsWithRecords(tx, input) {
const recipientIds = uniq(input.recipientEmployeeIds);
if (recipientIds.length === 0) {
return [];
}
const title = String(input.title ?? '').slice(0, 200);
const body = input.body != null ? String(input.body).slice(0, 5000) : null;
const type = String(input.type ?? '').slice(0, 64);
const targetType = input.targetType != null ? String(input.targetType).slice(0, 64) : null;
const created = [];
for (const recipientId of recipientIds) {
created.push(
await tx.notification.create({
data: {
recipient_employee_id: recipientId,
type,
title,
body,
target_type: targetType,
target_id: input.targetId ?? null,
},
}),
);
}
return created;
}
module.exports = {
createNotifications,
createNotificationsWithRecords,
resolveRecipientsForAssignee,
};