163 lines
5.7 KiB
JavaScript
163 lines
5.7 KiB
JavaScript
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;
|