import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid'; import { DATA_SUBSCRIBER_KEYS } from '../config/constants'; import assert from 'assert'; import { getShipClazz, getShipEntity } from '../utils/shipClazz'; import { notifyConfirmReceive, uploadShippingInfo } from '../utils/ship'; const triggers = [ { name: '当虚拟或自提类型的ship创建后自动发货', entity: 'ship', action: 'create', when: 'commit', strict: 'makeSure', asRoot: true, check: (operation) => ['virtual', 'pickup'].includes(operation.data.type), fn: async ({ ids }, context, option) => { for (const id of ids) { await context.operate('ship', { id: await generateNewIdAsync(), action: 'ship', data: {}, filter: { id, } }, option); } return; }, }, { name: '当物流类的ship创建后自动下单', entity: 'ship', action: 'create', when: 'commit', strict: 'makeSure', asRoot: true, check: (operation) => ['express'].includes(operation.data.type), fn: async ({ ids }, context, option) => { assert(ids.length === 1); const id = ids[0]; const [ship] = await context.select('ship', { data: { id: 1, entity: 1, entityId: 1, shipServiceId: 1, }, filter: { id } }, { dontCollect: true, forUpdate: true }); const { entity, entityId } = ship; if (entity && entityId) { const shipClazz = await getShipClazz(entity, entityId, context); const extraShipId = await shipClazz.eOrder(id, context); return { extraShipId, }; } } }, { // todo,deposit的ship和 shipClazz中有配置wechatShip且可获取openId的order的ship entity: 'ship', name: '当虚拟的ship变为shipping状态时,调用小程序发货信息录入接口', action: 'ship', when: 'before', asRoot: true, priority: 99, fn: async ({ operation }, context) => { const { data, filter } = operation; const [ship] = await context.select('ship', { data: { id: 1, type: 1, deposit$ship: { $entity: 'deposit', data: { id: 1, }, }, entity: 1, entityId: 1, shipServiceId: 1, shipOrder$ship: { $entity: 'shipOrder', data: { id: 1, orderId: 1, } }, wechatMpShip: { id: 1, applicationId: 1, } }, filter, }, {}); const { id: shipId, type, deposit$ship: deposits, shipOrder$ship, shipServiceId, entity, entityId, wechatMpShip } = ship || {}; if (deposits && deposits.length > 0) { //充值 (此时该充值必定为受发货限制的小程序上的充值) await uploadShippingInfo(shipId, context); return 1; } if (shipOrder$ship && shipOrder$ship.length > 0) { //订单 const clazz = await getShipClazz(entity, entityId, context); const { openId } = await clazz.getReceiverInfo(shipOrder$ship.map((ele) => ele.orderId), wechatMpShip?.applicationId, context); if (openId) { //当存在openId时调用小程序发货信息录入 await uploadShippingInfo(shipId, context); return 1; } } return 0; } }, { entity: 'ship', name: '当ship状态发生变化时,尝试向订阅者推送', action: ['ship', 'receive', 'giveUp', 'reject'], when: 'after', fn: async ({ operation }, context, option) => { const { filter, id } = operation; const { id: shipId } = filter; if (shipId) { context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.shipStateChanged}-${shipId}`); } return 1; } }, { name: '当物流创建时,将对应的receivingMethod为express的order变为packaged状态', entity: 'ship', action: 'create', when: 'after', fn: async ({ operation }, context, option) => { const { data } = operation; const orders = await context.select('order', { data: { id: 1, gState: 1, }, filter: { receivingMethod: 'express', shipOrder$order: { shipId: data.id, } } }, { dontCollect: true }); if (orders && orders.length > 0) { orders.forEach(ele => assert(ele.gState === 'unshipped')); await context.operate('order', { id: await generateNewIdAsync(), action: 'package', data: {}, filter: { id: { $in: orders.map(ele => ele.id), }, }, }, option); return orders.length; } return 0; } }, { name: '当物流创建时,赋上对应的物流系统对象', entity: 'ship', action: 'create', when: 'before', priority: 75, check: (operation) => operation.data.shipOrder$ship && operation.data.shipOrder$ship.length > 0, fn: async ({ operation }, context) => { const { data } = operation; let count = 0; if (data instanceof Array) { for (const d of data) { const { shipServiceId, shipOrder$ship } = d; assert(shipServiceId); const result = await getShipEntity(shipServiceId, shipOrder$ship.map(ele => ele.data.orderId), context); if (result) { d.entity = result[0]; d.entityId = result[1]; count++; } } } else { const { shipServiceId, shipOrder$ship } = data; assert(shipServiceId); const result = await getShipEntity(shipServiceId, shipOrder$ship.map(ele => ele.data.orderId), context); if (result) { data.entity = result[0]; data.entityId = result[1]; count++; } } return count; } }, { name: '当物流发货时,将对应的order状态变为已发货/提货中', entity: 'ship', action: 'ship', when: 'after', fn: async ({ operation }, context, option) => { const { filter } = operation; assert(typeof filter.id === 'string'); const orders = await context.select('order', { data: { id: 1, gState: 1, }, filter: { shipOrder$order: { shipId: filter.id, } } }, { dontCollect: true }); const packaged = orders.filter(ele => ele.gState === 'packaged'); if (packaged.length > 0) { await context.operate('order', { id: await generateNewIdAsync(), action: 'send', data: {}, filter: { id: { $in: packaged.map(ele => ele.id), }, }, }, option); } const staged = orders.filter(ele => ele.gState === 'staging'); if (staged.length > 0) { await context.operate('order', { id: await generateNewIdAsync(), action: 'startTaking', data: {}, filter: { id: { $in: staged.map(ele => ele.id), }, }, }, option); } assert(staged.length + packaged.length === orders.length); return orders.length; } }, { name: '当物流取消时,将对应的order状态改回packaged/staging', entity: 'ship', action: 'cancel', when: 'after', fn: async ({ operation }, context, option) => { const { filter } = operation; assert(typeof filter.id === 'string'); const orders = await context.select('order', { data: { id: 1, gState: 1, receivingMethod: 1, }, filter: { shipOrder$order: { shipId: filter.id, } } }, { dontCollect: true }); if (orders && orders.length > 0) { await context.operate('order', { id: await generateNewIdAsync(), action: 'unship', data: {}, filter: { id: { $in: orders.map(ele => ele.id), }, }, }, option); return orders.length; } return 0; } }, { name: '当物流类的ship取消后,调用外部接口取消下单', entity: 'ship', action: 'cancel', when: 'commit', strict: 'makeSure', asRoot: true, filter: { type: 'express', entity: { $exists: true, }, extraShipId: { $exists: true, }, }, fn: async ({ ids }, context, option) => { assert(ids.length === 1); const id = ids[0]; const [ship] = await context.select('ship', { data: { id: 1, entity: 1, entityId: 1, shipServiceId: 1, extraShipId: 1, }, filter: { id } }, { dontCollect: true, forUpdate: true }); const { entity, entityId, extraShipId } = ship; if (entity && entityId && extraShipId) { const shipClazz = await getShipClazz(entity, entityId, context); await shipClazz.cancelOrder(extraShipId, context); } } }, { name: '当ship签收后,调用小程序确认收货提醒', entity: 'ship', action: 'receive', when: 'commit', asRoot: true, filter: { receiveAt: { $exists: true, } }, fn: async ({ ids }, context, option) => { assert(ids.length === 1); const id = ids[0]; const [ship] = await context.select('ship', { data: { id: 1, entity: 1, entityId: 1, shipServiceId: 1, extraShipId: 1, receiveAt: 1, shipOrder$ship: { $entity: 'shipOrder', data: { id: 1, orderId: 1, } }, wechatMpShip: { id: 1, applicationId: 1, } }, filter: { id } }, { dontCollect: true, forUpdate: true }); const { entity, entityId, extraShipId, shipOrder$ship, wechatMpShip } = ship; if (entity && entityId && extraShipId && shipOrder$ship) { const shipClazz = await getShipClazz(entity, entityId, context); const { openId } = await shipClazz.getReceiverInfo(shipOrder$ship.map((ele) => ele.orderId), wechatMpShip?.applicationId, context); if (openId) { //当存在openId时调用小程序发货信息录入 await notifyConfirmReceive(id, context); return 1; } } } }, ]; export default triggers;