import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid'; import { assert } from 'oak-domain/lib/utils/assert'; import { uniqBy } from 'oak-domain/lib/utils/lodash'; import { getMessageHandler } from '../utils/message'; const InitialChannelByWeightMatrix = { high: ['wechatMp', 'wechatPublic', 'sms', 'email'], medium: ['wechatMp', 'wechatPublic', 'email'], low: ['wechatMp', 'wechatPublic', 'email'], }; async function createNotification(message, context) { const { restriction, userId, weight, type, entity, entityId, platformId, channels } = message; assert(userId); // 根据用户所关联的system和定义限制,选择将要发送的system。这里有的应用是到platform级别,有的是到system级别 const filter = { userId, }; if (platformId) { filter.system = { platformId, }; } const userSystems = await context.select('userSystem', { data: { id: 1, system: { id: 1, config: 1, application$system: { $entity: 'application', data: { id: 1, type: 1, config: 1, }, }, }, }, filter, }, { dontCollect: true }); // 这里实测线上跑出来多条相同的userSystem,还未知道原因 by Xc 20230317 const systems = uniqBy(userSystems.map(ele => ele.system).filter(ele => { if (restriction && restriction.systemIds) { return restriction.systemIds.includes(ele.id); } return true; }), 'id'); if (systems.length === 0) { console.warn(`类型为${type}的消息在生成时,尝试为之生成通知,找不到可推送的system`); return 0; } const messageTypeTemplates = await context.select('messageTypeTemplate', { data: { id: 1, templateId: 1, template: { id: 1, wechatId: 1, applicationId: 1, }, type: 1, }, filter: { type, template: { application: { systemId: { $in: systems.map(ele => ele.id), }, }, }, }, }, { dontCollect: true }); // 根据定义所限制的渠道和weight,计算出相应的推送渠道 const channels2 = ((channels && channels.length > 0) ? channels : InitialChannelByWeightMatrix[weight]).filter(ele => { if (restriction && restriction.channels) { return restriction.channels.includes(ele); } return true; }); /* if (channels.length === 0) { console.warn(`类型为${type}的消息在生成时,尝试为之生成通知,找不到可推送的channel`); return 0; } */ // 逐system逐channel去构造messageSystem和messageSent数据 let messageSentCount = 0; const messageSystemDatas = []; await Promise.all(systems.map(async (system) => { const { application$system: applications, config } = system; const notificationDatas = []; await Promise.all(channels2.map(async (channel) => { const handler = getMessageHandler(channel); const channelNotifications = await handler({ message, applications: applications, system, messageTypeTemplates, context, }); notificationDatas.push(...channelNotifications); })); const messageSystemData = { id: await generateNewIdAsync(), messageId: message.id, systemId: system.id, }; if (notificationDatas.length > 0) { messageSentCount += notificationDatas.length; messageSystemData.notification$messageSystem = [ { id: await generateNewIdAsync(), action: 'create', data: notificationDatas, } ]; } messageSystemDatas.push(messageSystemData); })); if (messageSystemDatas.length > 0) { message.messageSystem$message = [ { id: await generateNewIdAsync(), action: 'create', data: messageSystemDatas, } ]; } message.iState = messageSentCount ? 'sending' : 'failure'; return messageSentCount; } const triggers = [ { name: '当创建message时,创建相应的通知数据', entity: 'message', action: 'create', when: 'before', fn: async ({ operation }, context, params) => { const { data } = operation; let count = 0; const closeRootMode = context.openRootMode(); try { if (data instanceof Array) { for (const d of data) { count += await createNotification(d, context); } } else { count = await createNotification(data, context); } } catch (err) { closeRootMode(); throw err; } closeRootMode(); return count; } }, ]; export default triggers;