oak-pay-business/src/components/order/pay/index.ts

165 lines
5.6 KiB
TypeScript
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 { EntityDict } from "../../../oak-app-domain";
import { generateNewId, generateNewIdAsync } from "oak-domain/lib/utils/uuid";
import { ToCent, ToYuan } from "oak-domain/lib/utils/money";
import { PayChannel } from "../../../types/Pay";
export default OakComponent({
entity: 'order',
projection: {
id: 1,
price: 1,
paid: 1,
iState: 1,
pay$order: {
$entity: 'pay',
data: {
id: 1,
price: 1,
paid: 1,
iState: 1,
entity: 1,
entityId: 1,
},
filter: {
iState: 'paying',
},
},
},
isList: false,
properties: {
accountId: '', // 是否可以使用帐户中的余额抵扣
accountAvailMax: 0, // 本次交易可以使用的帐户中的Avail max值调用者自己保证此数值的一致性不要扣成负数
onSetPays: (pays: Partial<EntityDict['pay']['CreateOperationData']>[]) => undefined as void,
accountTips: '', // 使用余额支付的提示说明
autoStartPay: false,
},
formData({ data }) {
const payChannels = features.pay.getPayChannels('pay');
const activePay = data && data.pay$order?.[0];
const { accountPrice } = this.state;
const { accountAvailMax } = this.props;
const rest = data ? data.price! - data.paid! - accountPrice : 0;
return {
priceStr: data && ToYuan(data.price!),
accountAvailMaxStr: accountAvailMax && ToYuan(accountAvailMax),
order: data,
activePay,
rest,
restYuan: ToYuan(rest),
legal: !!(data?.['#oakLegalActions']?.includes('startPaying')),
payChannels,
};
},
features: ['application'],
data: {
useAccount: false,
accountPrice: 0,
accountPriceYuan: 0,
channel: undefined as PayChannel | undefined,
restYuan: 0,
meta: undefined as undefined | object,
onPickMp(channel: string) {
this.onPickChannel(channel);
},
onSetMetaMp(meta?: object) {
this.onSetChannelMeta(meta);
}
},
methods: {
switchUseAccount() {
const { accountAvailMax } = this.props;
const { useAccount, order } = this.state;
const accountMaxPrice = Math.min(accountAvailMax!, order!.price!);
if (!useAccount) {
const rest = order.price! - accountMaxPrice;
this.setState({
useAccount: true,
accountPrice: accountMaxPrice,
accountPriceYuan: ToYuan(accountMaxPrice),
rest,
restYuan: ToYuan(rest),
}, () => this.tryCreatePays());
}
else {
const rest = order.price!;
this.setState({
useAccount: false,
accountPrice: undefined,
accountPriceYuan: undefined,
rest,
restYuan: ToYuan(rest),
}, () => this.tryCreatePays())
}
},
setAccountPrice(price: number) {
const { order } = this.state;
const rest = order!.price! - order!.paid! - price;
this.setState({
accountPrice: price,
rest,
restYuan: ToYuan(rest),
accountPriceYuan: ToYuan(price),
}, () => this.tryCreatePays());
},
setAccountPriceMp(e: WechatMiniprogram.Input) {
const { value } = e.detail;
const v = parseInt(value);
if (!isNaN(v)) {
const { accountAvailMax } = this.props;
const { order } = this.state;
const accountMaxPrice = Math.min(accountAvailMax!, order!.price!);
this.setAccountPrice(Math.min(accountMaxPrice, ToCent(v)));
}
},
onPickChannel(channel: PayChannel) {
this.setState({
channel,
}, () => this.tryCreatePays());
},
onSetChannelMeta(meta?: object) {
this.setState({
meta,
}, () => this.tryCreatePays());
},
tryCreatePays() {
const { accountId, autoStartPay } = this.props;
const { useAccount, accountPrice, channel, meta, order } = this.state;
const pays: Partial<EntityDict['pay']['CreateOperationData']>[] = [];
let rest = order!.price! - order!.paid!;
let payId = '';
if (useAccount && accountPrice) {
pays.push({
id: generateNewId(),
entity: 'account',
entityId: accountId,
price: accountPrice,
autoStart: !!autoStartPay,
});
rest = rest - accountPrice;
}
if (rest && channel) {
payId = generateNewId();
pays.push({
id: payId,
entity: channel.entity,
entityId: channel.entityId,
meta,
price: rest,
autoStart: !!autoStartPay,
});
rest = 0;
}
const { onSetPays } = this.props;
if (rest === 0) {
onSetPays!(pays);
}
else {
onSetPays!([]);
}
}
},
actions: ['startPaying'],
});