165 lines
5.6 KiB
TypeScript
165 lines
5.6 KiB
TypeScript
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'],
|
||
});
|
||
|