oak-pay-business/es/components/pay/detail/index.js

304 lines
10 KiB
JavaScript
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 { CentToString } from "oak-domain/lib/utils/money";
import { DATA_SUBSCRIBER_KEYS } from "../../../config/constants";
import assert from "assert";
import { isWeiXin } from 'oak-frontend-base/es/utils/utils';
import { merge } from "oak-domain/lib/utils/lodash";
import { canStartPay } from "../../../utils/wpProductFrontend";
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
const PayRoutineDict = {
wpProduct: {
projection: {
wpProduct: {
id: 1,
type: 1,
},
},
routine: async (pay, features) => {
const { iState, wpProduct, meta } = pay;
switch (wpProduct.type) {
case 'mp': {
if (process.env.OAK_PLATFORM === 'wechatMp') {
const { prepayMeta } = meta;
if (prepayMeta) {
const result = await wx.requestPayment(prepayMeta);
process.env.NODE_ENV === 'development' && console.log(result);
}
else {
features.message.setMessage({
type: 'error',
content: features.locales.t('startPayError.illegaPayData'),
});
}
}
else {
features.message.setMessage({
type: 'error',
content: features.locales.t('startPayError.falseEnv', { env: 'wechatMp' }),
});
}
return;
}
case 'jsapi': {
if (process.env.OAK_PLATFORM === 'web' && isWeiXin) {
const { prepayMeta } = meta;
if (prepayMeta) {
const { timeStamp, ...rest } = prepayMeta;
// chooseWXPay文档都找不到了网上查出来这里timestamp的s要小写吐血了
await features.wechatSdk.loadWxAPi('chooseWXPay', {
timestamp: timeStamp,
...rest,
});
}
else {
features.message.setMessage({
type: 'error',
content: features.locales.t('startPayError.illegaPayData'),
});
}
}
}
default: {
assert('尚未实现');
}
}
},
judgeCanPay: canStartPay,
}
};
export function registerFrontendPayRoutine(entity, routine, projection, judgeCanPay) {
PayRoutineDict[entity] = {
routine,
projection,
judgeCanPay,
};
}
export default OakComponent({
entity: 'pay',
isList: false,
projection: () => {
const baseProjection = {
id: 1,
applicationId: 1,
price: 1,
meta: 1,
iState: 1,
paid: 1,
refunded: 1,
timeoutAt: 1,
forbidRefundAt: 1,
externalId: 1,
orderId: 1,
depositId: 1,
deposit: {
id: 1,
accountId: 1,
price: 1,
loss: 1,
},
order: {
id: 1,
creatorId: 1,
},
entity: 1,
entityId: 1,
creatorId: 1,
phantom3: 1,
};
for (const k in PayRoutineDict) {
merge(baseProjection, PayRoutineDict[k].projection);
}
return baseProjection;
},
properties: {
onClose: () => undefined,
disableAutoPay: false,
},
data: {
showCloseConfirmMp: false,
showChannelSelectMp: false,
},
formData({ data }) {
const application = this.features.application.getApplication();
const iState = data?.iState;
const iStateColor = iState && this.features.style.getColor('pay', 'iState', iState);
const startPayable = iState === 'paying' && !['account', 'offlineAccount'].includes(data.entity) && (PayRoutineDict[data.entity] && PayRoutineDict[data.entity].judgeCanPay(data, this.features));
const payChannels = this.features.pay.getPayChannels();
const offlines = this.features.cache.get('offlineAccount', {
data: {
id: 1,
type: 1,
channel: 1,
name: 1,
qrCode: 1,
},
filter: {
systemId: this.features.application.getApplication().systemId,
}
}).map(ele => {
const color = this.features.style.getColor('offlineAccount', 'type', ele.type);
return {
color,
...ele,
};
});
const offline = offlines?.find(ele => ele.id === data.entityId);
return {
type: data?.orderId ? 'order' : 'deposit',
pay: data,
application,
iStateColor,
closable: !!(data?.["#oakLegalActions"]?.includes('close')),
startPayable,
offline,
offlines,
notSameApp: data && data.applicationId !== application.id && data.entity !== 'offlineAccount',
priceStr: data?.price && CentToString(data.price, 2),
};
},
features: [{
feature: 'application',
callback() {
this.refreshOfflineAccounts();
}
}],
actions: ['close', 'startPaying', {
action: 'update',
attrs: ['entityId'],
}],
methods: {
refreshOfflineAccounts() {
const { entity } = this.state.pay || {};
if (entity === 'offlineAccount') {
this.features.cache.refresh('offlineAccount', {
data: {
id: 1,
channel: 1,
name: 1,
type: 1,
qrCode: 1,
},
filter: {
systemId: this.features.application.getApplication().systemId,
}
});
}
},
executeMp() {
return this.execute();
},
resetMp() {
return this.clean();
},
closeMp() {
this.setState({
showCloseConfirmMp: true,
});
},
cancelCloseMp() {
this.setState({
showCloseConfirmMp: false,
});
},
async confirmCloseMp() {
await this.execute('close');
this.cancelCloseMp();
},
goBack() {
this.navigateBack();
},
async startPay() {
const { pay } = this.state;
await PayRoutineDict[pay.entity].routine(pay, this.features);
},
/* async onWxBridgeReady(payMetaData: any): Promise<void> {
return new Promise(
(resolve, reject) => {
WeixinJSBridge.invoke('getBrandWCPayRequest', payMetaData,
function (res: { err_msg: string }) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok但并不保证它绝对可靠。
resolve(undefined as void);
}
else {
reject(res.err_msg);
}
}
);
}
);
} */
openChannelSelectMp() {
this.setState({
showChannelSelectMp: true,
});
},
closeChannelSelectMp() {
this.setState({
showChannelSelectMp: false,
});
},
async updateOfflineIdMp(touch) {
const { detail } = touch;
const { currentKey } = detail;
const { oakId } = this.props;
if (currentKey) {
await this.execute(undefined, undefined, undefined, [
{
entity: 'pay',
operation: {
id: await generateNewIdAsync(),
action: 'update',
data: {
entity: 'offlineAccount',
entityId: currentKey,
},
filter: {
id: oakId,
},
}
}
]);
this.setState({
showChannelSelectMp: false,
});
}
},
updateExternalIdMp(input) {
const { detail } = input;
this.update({
externalId: detail.value,
});
},
clearExternalIdMp() {
this.update({
externalId: null,
});
}
},
lifetimes: {
ready() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`], 'opb-c-pay-detail');
},
detached() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.unsubDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`], 'opb-c-pay-detail');
}
},
listeners: {
startPayable(prev, next) {
if (next.startPayable && !this.props.disableAutoPay) {
this.startPay();
}
},
pay(prev, next) {
if (!prev.pay && next.pay) {
this.refreshOfflineAccounts();
}
}
},
});