import { OakAttrNotNullException, OakInputIllegalException } from 'oak-domain/lib/types'; import { pipeline } from 'oak-domain/lib/utils/executor'; import assert from 'assert'; const checkers = [ { entity: 'pay', type: 'logical', action: 'create', checker(operation, context) { const { data } = operation; data.refunded = 0; data.paid = 0; data.applicationId = context.getApplicationId(); data.creatorId = context.getCurrentUserId(); data.refundable = false; if (!data.meta) { data.meta = {}; } }, }, { entity: 'pay', type: 'data', action: 'create', checker(data) { const { entity, entityId, price, orderId, depositId } = data; if (price <= 0) { throw new OakInputIllegalException('pay', ['price'], '支付金额必须大于0'); } if (!orderId) { // 充值类订单 if (!depositId) { throw new OakInputIllegalException('pay', ['accountId'], '充值类支付必须指定accountId'); } else if (entity === 'account') { throw new OakInputIllegalException('pay', ['channel'], '充值类支付不能使用帐户支付'); } } } }, { entity: 'pay', type: 'logicalData', action: 'create', checker(operation, context) { const { data } = operation; const { orderId, price } = data; data.refundable = false; if (orderId) { // 所有已经支付和正在支付的pay之和不能超过订单总和 const order = context.select('order', { data: { id: 1, price: 1, pay$order: { $entity: 'pay', data: { id: 1, price: 1, }, filter: { iState: { $in: ['paying', 'paid'], } } } }, filter: { id: orderId, } }, {}); const checkPays = (order) => { const { price: orderPrice, pay$order: pays } = order; let pricePaying = 0; pays.forEach((pay) => pricePaying += pay.price); if (pricePaying + price > orderPrice) { throw new OakInputIllegalException('pay', ['price'], 'pay.create.priceOverflow'); } }; if (order instanceof Promise) { return order.then(([o]) => checkPays(o)); } return checkPays(order[0]); } } }, { entity: 'pay', action: 'succeedPaying', type: 'row', filter(operation, context) { const isRoot = context.isRoot(); if (isRoot) { return {}; } // 非root用户只能手动成功offline类型的pay return { entity: 'offlineAccount', }; } }, { entity: 'pay', action: 'succeedPaying', type: 'logicalData', checker(operation, context) { const { data, filter } = operation; assert(!(data instanceof Array)); const { successAt, externalId } = data; if (!successAt) { throw new OakAttrNotNullException('pay', ['successAt']); } assert(typeof filter?.id === 'string'); // 必须有ExternalId,除非之间prepay的时候已经填过了 if (!externalId) { return pipeline(() => context.select('pay', { data: { id: 1, externalId: 1, entity: 1, }, filter: { id: filter.id, } }, { dontCollect: true }), (pays) => { const [pay] = pays; if (pay.entity !== 'account' && !pay.externalId) { throw new OakAttrNotNullException('pay', ['externalId']); } }); } } }, { // 如果在开始支付或者继续支付过程中,paid达到了price,pay的状态可以改为paid entity: 'pay', type: 'logical', action: ['continuePaying', 'startPaying'], // priority: CHECKER_MAX_PRIORITY - 1, // 要超过action矩阵定义的赋state值 checker: (operation, context) => { const { data, filter } = operation; assert(filter && typeof filter.id === 'string'); const { paid } = data || {}; if (paid) { return pipeline(() => context.select('pay', { data: { id: 1, paid: 1, price: 1, }, }, {}), (pays) => { const [pay] = pays; const { paid: payPaid, price } = pay; if (payPaid + paid === price) { data.iState === 'paid'; } }); } } } ]; export default checkers;