oak-pay-business/es/triggers/ship.js

377 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
};
}
}
},
{
// tododeposit的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;