import { fullPayProjection } from '../utils/pay'; import { getPayClazz } from '../utils/payClazz'; import assert from 'assert'; import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid'; import { mergeOperationResult } from 'oak-domain/lib/utils/operationResult'; const QUERY_PAYING_STATE_GAP = 3600 * 1000; const watchers = [ { name: '对paying状态的订单,同步其真实支付状态', entity: 'pay', filter: async () => { const now = Date.now(); return { iState: 'paying', $$updateAt$$: { $lte: now - QUERY_PAYING_STATE_GAP, }, externalId: { $exists: true, } }; }, projection: fullPayProjection, fn: async (context, data) => { const results = []; for (const pay of data) { const { applicationId, channel, timeoutAt } = pay; const clazz = await getPayClazz(applicationId, channel, context); const iState = await clazz.getState(pay); if (iState !== pay.iState) { let action = 'close'; switch (iState) { case 'closed': { // action = 'close'; break; } case 'paid': { action = 'succeedPaying'; break; } default: { assert(false); } } const result = await context.operate('pay', { id: await generateNewIdAsync(), action, data: {}, filter: { id: pay.id, } }, {}); results.push(result); } else if (iState === 'paying' && timeoutAt < Date.now()) { // 尝试关闭订单 // 理论上用户可能在上一个getState和这个close之间支付完成,此时关闭失败,下一个Watcher到来时就能处理成功了 const result = await context.operate('pay', { id: await generateNewIdAsync(), action: 'close', data: {}, filter: { id: pay.id, } }, {}); results.push(result); } } return results.reduce((prev, cur) => mergeOperationResult(prev, cur)); } } ]; export default watchers;