修正了pay的若干错误逻辑

This commit is contained in:
Xu Chang 2024-05-14 21:02:16 +08:00
parent 9af374e92c
commit a9c04496ae
31 changed files with 241 additions and 104 deletions

View File

@ -1,9 +1,8 @@
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, boolean, {
depositMax: number;
depositMaxCent: number;
onSetPrice: (price: null | number) => void;
onSetChannel: (channel: string) => void;
onSetMeta: (meta: any) => void;
price: number | null;
channel: string;
meta: any;
}>) => React.ReactElement;

View File

@ -2,11 +2,10 @@ import { ToCent, ToYuan } from 'oak-domain/lib/utils/money';
import { PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_OFFLINE_NAME } from '../../../types/PayConfig';
export default OakComponent({
properties: {
depositMax: 10000,
depositMaxCent: 1000000,
onSetPrice: (price) => undefined,
onSetChannel: (channel) => undefined,
onSetMeta: (meta) => undefined,
price: 0,
channel: '',
meta: {},
},
@ -22,11 +21,11 @@ export default OakComponent({
payConfig.push(config);
}
}
const price = this.props.price;
const { depositMaxCent } = this.props;
return {
depositMax: ToYuan(depositMaxCent),
account: data,
payConfig,
priceStr: typeof price == 'number' ? `${ToYuan(price)}` : undefined
// accountConfig,
};
},
@ -39,14 +38,21 @@ export default OakComponent({
methods: {
onDepPriceChangeMp(event) {
const { value } = event.detail;
const price = parseInt(value);
if (!isNaN(price)) {
this.props.onSetPrice(ToCent(price));
const { depositMaxCent } = this.props;
const price2 = parseInt(value);
if (!isNaN(price2)) {
const price = Math.min(depositMaxCent, ToCent(price2));
this.props.onSetPrice(price);
this.setState({
price,
priceStr: price ? `${ToYuan(price)}` : undefined
});
}
},
},
data: {
onChannelPickMp(channel) { this.props.onSetChannel(channel); },
onMetaSetMp(meta) { this.props.onSetMeta(meta); },
price: 0,
}
});

View File

@ -3,10 +3,10 @@
<l-form-item label="{{t('label.depPrice')}}">
<l-input
hide-label
value="{{priceStr}}"
value="{{priceStr || ''}}"
type="number"
bind:lininput="onDepPriceChangeMp"
placeholder="{{t('placeholder', { max: depositMax })}}"
placeholder="一次最大充值{{depositMax}}元"
/>
</l-form-item>
<view wx:if="{{price > 0}}">

View File

@ -1,5 +1,7 @@
import { CentToString } from "oak-domain/lib/utils/money";
import { generateNewIdAsync } from "oak-domain/lib/utils/uuid";
import assert from 'assert';
import { DATA_SUBSCRIBER_KEYS } from "../../../config/constants";
export default OakComponent({
entity: 'account',
isList: false,
@ -153,5 +155,17 @@ export default OakComponent({
setDepPriceMp(price) { this.setDepPrice(price); },
setDepositChannelMp(depositChannel) { this.setDepositChannel(depositChannel); },
setDepositMetaMp(depositMeta) { this.setDepositMeta(depositMeta); }
},
lifetimes: {
ready() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${oakId}`]);
},
detached() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.unsubDataEvents([`${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${oakId}`]);
}
}
});

View File

@ -29,41 +29,44 @@
</l-button>
</view>
</view>
<l-popup
show="{{depositOpen}}"
content-align="bottom"
bind:lintap="onDepositModalClose"
>
<view class="ad-container">
<account-deposit
depositMax='{{depositMax}}'
price='{{depPrice}}'
channel='{{depositChannel}}'
meta='{{depositMeta}}'
onSetPrice="{{setDepPriceMp}}"
onSetChannel="{{setDepositChannelMp}}"
onSetMeta="{{setDepositMetaMp}}"
/>
<view style="margin-top: 12rpx">
<l-button
type="default"
size="long"
disabled="{{!depPrice || !depositChannel || depositing}}"
loading="{{depositing}}"
bind:lintap="createDepositPay"
>
{{depositing ? t('depositing') : t('common::confirm')}}
</l-button>
<block wx:if="{{depositOpen}}">
<l-popup
show="{{depositOpen}}"
content-align="bottom"
bind:lintap="onDepositModalClose"
>
<view class="ad-container">
<account-deposit
depositMax='{{depositMax}}'
channel='{{depositChannel}}'
meta='{{depositMeta}}'
onSetPrice="{{setDepPriceMp}}"
onSetChannel="{{setDepositChannelMp}}"
onSetMeta="{{setDepositMetaMp}}"
/>
<view style="margin-top: 12rpx">
<l-button
type="default"
size="long"
disabled="{{!depPrice || !depositChannel || depositing}}"
loading="{{depositing}}"
bind:lintap="createDepositPay"
>
{{depositing ? t('depositing') : t('common::confirm')}}
</l-button>
</view>
</view>
</view>
</l-popup>
<l-dialog
show="{{ufOpen}}"
type="alert"
show-title="{{false}}"
content="{{t('uf.content')}}"
confirm-text="{{t('uf.go')}}"
bind:linconfirm="onUnfinishedPayClickedMp"
bind:lintap="onUfModalClose"
/>
</l-popup>
</block>
<block wx:if="{{ufOpen}}">
<l-dialog
show="{{ufOpen}}"
type="alert"
show-title="{{false}}"
content="{{t('uf.content')}}"
confirm-text="{{t('uf.go')}}"
bind:linconfirm="onUnfinishedPayClickedMp"
bind:lintap="onUfModalClose"
/>
</block>
</view>

View File

@ -50,7 +50,7 @@ export default function Render(props) {
</div>
<Popup visible={depositOpen} onMaskClick={() => onDepositModalClose()} onClose={() => onDepositModalClose()}>
<div style={{ padding: 12, marginBottom: 6 }}>
<AccountDeposit depositMax={depositMax} price={depPrice} channel={depositChannel} meta={depositMeta} onSetPrice={(price) => setDepPrice(price)} onSetChannel={(channel) => setDepositChannel(channel)} onSetMeta={(meta) => setDepositMeta(meta)}/>
<AccountDeposit depositMax={depositMax} channel={depositChannel} meta={depositMeta} onSetPrice={(price) => setDepPrice(price)} onSetChannel={(channel) => setDepositChannel(channel)} onSetMeta={(meta) => setDepositMeta(meta)}/>
<Button block loading={depositing} color="primary" disabled={!depPrice || !depositChannel || depositing} onClick={() => createDepositPay()}>
{depositing ? t('depositing') : t('common::confirm')}
</Button>

View File

@ -51,7 +51,7 @@ export default function Render(props) {
{depositing ? t('depositing') : t('common::confirm')}
</Button>}>
<div style={{ padding: 12 }}>
<AccountDeposit depositMax={depositMax} price={depPrice} channel={depositChannel} meta={depositMeta} onSetPrice={(price) => setDepPrice(price)} onSetChannel={(channel) => setDepositChannel(channel)} onSetMeta={(meta) => setDepositMeta(meta)}/>
<AccountDeposit depositMax={depositMax} channel={depositChannel} meta={depositMeta} onSetPrice={(price) => setDepPrice(price)} onSetChannel={(channel) => setDepositChannel(channel)} onSetMeta={(meta) => setDepositMeta(meta)}/>
</div>
</Modal>
<Modal title={t('uf.title')} open={ufOpen} onCancel={() => {

View File

@ -6,7 +6,6 @@
align-items: stretch;
flex-direction: column;
height: 100%;
padding: 40rpx;
.info {
background-color: @oak-bg-color-container;

View File

@ -1,3 +1,4 @@
export declare const DATA_SUBSCRIBER_KEYS: {
payStateChanged: string;
accountNumberChanged: string;
};

View File

@ -1,3 +1,4 @@
export const DATA_SUBSCRIBER_KEYS = {
payStateChanged: 'oak-pay-business-psc',
accountNumberChanged: 'oak-pay-business-anc',
};

View File

@ -1,13 +1,14 @@
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import assert from 'assert';
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
const triggers = [
{
name: '当生成accountOper时修改account中的值',
name: '当生成accountOper时修改account中的值,并向订阅者推送',
entity: 'accountOper',
action: 'create',
when: 'after',
fn: async ({ operation }, context, option) => {
const { data } = operation;
const { id, data } = operation;
assert(!(data instanceof Array));
const { accountId, totalPlus, availPlus, type } = data;
const [account] = await context.select('account', {
@ -32,6 +33,7 @@ const triggers = [
id: accountId,
}
}, option);
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${accountId}`);
return 1;
},
}

5
es/triggers/acount.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { Trigger } from 'oak-domain/lib/types/Trigger';
import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
declare const triggers: Trigger<EntityDict, 'account', BRC>[];
export default triggers;

20
es/triggers/acount.js Normal file
View File

@ -0,0 +1,20 @@
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
import assert from 'assert';
const triggers = [
{
name: '当account帐户的值发生变化时向订阅者推送',
entity: 'account',
action: ['deposit', 'withdraw', 'withdrawBack', 'consume', 'loan', 'repay'],
check(operation) {
return operation.data.hasOwnProperty('total') || operation.data.hasOwnProperty('avail');
},
when: 'after',
fn: async ({ operation }, context, option) => {
const { id, filter } = operation;
assert(typeof filter?.id === 'string');
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${filter.id}`);
return 1;
},
},
];
export default triggers;

View File

@ -1,9 +1,11 @@
import aoTriggers from './accountOper';
import payTriggers from './pay';
import userSystemTriggers from './userSystem';
import accountTriggers from './acount';
const triggers = [
...aoTriggers,
...payTriggers,
...userSystemTriggers,
...accountTriggers,
];
export default triggers;

View File

@ -1,3 +1,4 @@
export declare const DATA_SUBSCRIBER_KEYS: {
payStateChanged: string;
accountNumberChanged: string;
};

View File

@ -3,4 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.DATA_SUBSCRIBER_KEYS = void 0;
exports.DATA_SUBSCRIBER_KEYS = {
payStateChanged: 'oak-pay-business-psc',
accountNumberChanged: 'oak-pay-business-anc',
};

View File

@ -3,14 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const assert_1 = tslib_1.__importDefault(require("assert"));
const constants_1 = require("../config/constants");
const triggers = [
{
name: '当生成accountOper时修改account中的值',
name: '当生成accountOper时修改account中的值,并向订阅者推送',
entity: 'accountOper',
action: 'create',
when: 'after',
fn: async ({ operation }, context, option) => {
const { data } = operation;
const { id, data } = operation;
(0, assert_1.default)(!(data instanceof Array));
const { accountId, totalPlus, availPlus, type } = data;
const [account] = await context.select('account', {
@ -35,6 +36,7 @@ const triggers = [
id: accountId,
}
}, option);
context.saveOperationToEvent(id, `${constants_1.DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${accountId}`);
return 1;
},
}

5
lib/triggers/acount.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { Trigger } from 'oak-domain/lib/types/Trigger';
import { EntityDict } from '../oak-app-domain';
import { BRC } from '../types/RuntimeCxt';
declare const triggers: Trigger<EntityDict, 'account', BRC>[];
export default triggers;

23
lib/triggers/acount.js Normal file
View File

@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const constants_1 = require("../config/constants");
const assert_1 = tslib_1.__importDefault(require("assert"));
const triggers = [
{
name: '当account帐户的值发生变化时向订阅者推送',
entity: 'account',
action: ['deposit', 'withdraw', 'withdrawBack', 'consume', 'loan', 'repay'],
check(operation) {
return operation.data.hasOwnProperty('total') || operation.data.hasOwnProperty('avail');
},
when: 'after',
fn: async ({ operation }, context, option) => {
const { id, filter } = operation;
(0, assert_1.default)(typeof filter?.id === 'string');
context.saveOperationToEvent(id, `${constants_1.DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${filter.id}`);
return 1;
},
},
];
exports.default = triggers;

View File

@ -4,9 +4,11 @@ const tslib_1 = require("tslib");
const accountOper_1 = tslib_1.__importDefault(require("./accountOper"));
const pay_1 = tslib_1.__importDefault(require("./pay"));
const userSystem_1 = tslib_1.__importDefault(require("./userSystem"));
const acount_1 = tslib_1.__importDefault(require("./acount"));
const triggers = [
...accountOper_1.default,
...pay_1.default,
...userSystem_1.default,
...acount_1.default,
];
exports.default = triggers;

View File

@ -3,11 +3,10 @@ import { AccountPayConfig, OfflinePayConfig,
PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_OFFLINE_NAME } from '../../../types/PayConfig';
export default OakComponent({
properties: {
depositMax: 10000,
depositMaxCent: 1000000,
onSetPrice: (price: null | number) => undefined as void,
onSetChannel: (channel: string) => undefined as void,
onSetMeta: (meta: any) => undefined as void,
price: 0 as number | null,
channel: '',
meta: {} as any,
},
@ -23,11 +22,11 @@ export default OakComponent({
payConfig.push(config);
}
}
const price = this.props.price;
const { depositMaxCent } = this.props;
return {
depositMax: ToYuan(depositMaxCent!),
account: data,
payConfig,
priceStr: price ? `${ToYuan(price)}` : undefined
// accountConfig,
};
},
@ -40,14 +39,21 @@ export default OakComponent({
methods: {
onDepPriceChangeMp(event: WechatMiniprogram.Input) {
const { value } = event.detail;
const price = parseInt(value);
if (!isNaN(price)) {
this.props.onSetPrice!(ToCent(price));
const { depositMaxCent } = this.props;
const price2 = parseInt(value);
if (!isNaN(price2)) {
const price = Math.min(depositMaxCent!, ToCent(price2));
this.props.onSetPrice!(price);
this.setState({
price,
priceStr: price ? `${ToYuan(price)}` : undefined
})
}
},
},
data: {
onChannelPickMp(channel: string) { this.props.onSetChannel!(channel ); },
onMetaSetMp(meta: any) { this.props.onSetMeta!(meta); },
price: 0 as number | null,
}
})

View File

@ -6,7 +6,7 @@
value="{{priceStr || ''}}"
type="number"
bind:lininput="onDepPriceChangeMp"
placeholder="{{t('placeholder', { max: depositMax })}}"
placeholder="一次最大充值{{depositMax}}元"
/>
</l-form-item>
<view wx:if="{{price > 0}}">

View File

@ -1,5 +1,7 @@
import { CentToString } from "oak-domain/lib/utils/money";
import { generateNewIdAsync } from "oak-domain/lib/utils/uuid";
import assert from 'assert';
import { DATA_SUBSCRIBER_KEYS } from "../../../config/constants";
export default OakComponent({
entity: 'account',
@ -50,7 +52,6 @@ export default OakComponent({
properties: {
depositMax: 10000,
onDepositPayId: (payId: string) => undefined as void,
},
formData({ data }) {
const unfinishedPayId = data?.pay$account?.[0]?.id;
@ -156,5 +157,17 @@ export default OakComponent({
setDepPriceMp(price: number | null) { this.setDepPrice(price)},
setDepositChannelMp(depositChannel: string | undefined) { this.setDepositChannel(depositChannel)},
setDepositMetaMp(depositMeta: any) { this.setDepositMeta(depositMeta)}
},
lifetimes: {
ready() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${oakId}`]);
},
detached() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.unsubDataEvents([`${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${oakId}`]);
}
}
})

View File

@ -29,41 +29,44 @@
</l-button>
</view>
</view>
<l-popup
show="{{depositOpen}}"
content-align="bottom"
bind:lintap="onDepositModalClose"
>
<view class="ad-container">
<account-deposit
depositMax='{{depositMax}}'
price='{{depPrice}}'
channel='{{depositChannel}}'
meta='{{depositMeta}}'
onSetPrice="{{setDepPriceMp}}"
onSetChannel="{{setDepositChannelMp}}"
onSetMeta="{{setDepositMetaMp}}"
/>
<view style="margin-top: 12rpx">
<l-button
type="default"
size="long"
disabled="{{!depPrice || !depositChannel || depositing}}"
loading="{{depositing}}"
bind:lintap="createDepositPay"
>
{{depositing ? t('depositing') : t('common::confirm')}}
</l-button>
<block wx:if="{{depositOpen}}">
<l-popup
show="{{depositOpen}}"
content-align="bottom"
bind:lintap="onDepositModalClose"
>
<view class="ad-container">
<account-deposit
depositMax='{{depositMax}}'
channel='{{depositChannel}}'
meta='{{depositMeta}}'
onSetPrice="{{setDepPriceMp}}"
onSetChannel="{{setDepositChannelMp}}"
onSetMeta="{{setDepositMetaMp}}"
/>
<view style="margin-top: 12rpx">
<l-button
type="default"
size="long"
disabled="{{!depPrice || !depositChannel || depositing}}"
loading="{{depositing}}"
bind:lintap="createDepositPay"
>
{{depositing ? t('depositing') : t('common::confirm')}}
</l-button>
</view>
</view>
</view>
</l-popup>
<l-dialog
show="{{ufOpen}}"
type="alert"
show-title="{{false}}"
content="{{t('uf.content')}}"
confirm-text="{{t('uf.go')}}"
bind:linconfirm="onUnfinishedPayClickedMp"
bind:lintap="onUfModalClose"
/>
</l-popup>
</block>
<block wx:if="{{ufOpen}}">
<l-dialog
show="{{ufOpen}}"
type="alert"
show-title="{{false}}"
content="{{t('uf.content')}}"
confirm-text="{{t('uf.go')}}"
bind:linconfirm="onUnfinishedPayClickedMp"
bind:lintap="onUfModalClose"
/>
</block>
</view>

View File

@ -118,7 +118,6 @@ export default function Render(props: WebComponentProps<EntityDict, 'account', f
<div style={{ padding: 12 }}>
<AccountDeposit
depositMax={depositMax}
price={depPrice}
channel={depositChannel}
meta={depositMeta}
onSetPrice={(price) => setDepPrice(price)}

View File

@ -97,7 +97,6 @@ export default function Render(props: WebComponentProps<EntityDict, 'account', f
<div style={{ padding: 12, marginBottom: 6 }}>
<AccountDeposit
depositMax={depositMax}
price={depPrice}
channel={depositChannel}
meta={depositMeta}
onSetPrice={(price) => setDepPrice(price)}

View File

@ -6,7 +6,6 @@
align-items: stretch;
flex-direction: column;
height: 100%;
padding: 40rpx;
.info {
background-color: @oak-bg-color-container;

View File

@ -1,3 +1,4 @@
export const DATA_SUBSCRIBER_KEYS = {
payStateChanged: 'oak-pay-business-psc',
accountNumberChanged: 'oak-pay-business-anc',
};

View File

@ -3,15 +3,16 @@ import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import { EntityDict } from '../oak-app-domain';
import { BRC } from '@project/types/RuntimeCxt';
import assert from 'assert';
import { DATA_SUBSCRIBER_KEYS } from '@project/config/constants';
const triggers: Trigger<EntityDict, 'accountOper', BRC>[] = [
{
name: '当生成accountOper时修改account中的值',
name: '当生成accountOper时修改account中的值,并向订阅者推送',
entity: 'accountOper',
action: 'create',
when: 'after',
fn: async ({ operation }, context, option) => {
const { data } = operation;
const { id, data } = operation;
assert(!(data instanceof Array));
const { accountId, totalPlus, availPlus, type } = data;
const [account] = await context.select('account', {
@ -38,6 +39,8 @@ const triggers: Trigger<EntityDict, 'accountOper', BRC>[] = [
}
}, option);
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${accountId}`);
return 1;
},
} as CreateTriggerInTxn<EntityDict, 'accountOper', BRC>

26
src/triggers/acount.ts Normal file
View File

@ -0,0 +1,26 @@
import { CreateTriggerInTxn, Trigger, UpdateTriggerInTxn } from 'oak-domain/lib/types/Trigger';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import { EntityDict } from '../oak-app-domain';
import { BRC } from '@project/types/RuntimeCxt';
import { DATA_SUBSCRIBER_KEYS } from '@project/config/constants';
import assert from 'assert';
const triggers: Trigger<EntityDict, 'account', BRC>[] = [
{
name: '当account帐户的值发生变化时向订阅者推送',
entity: 'account',
action: ['deposit', 'withdraw', 'withdrawBack', 'consume', 'loan', 'repay'],
check(operation) {
return operation.data.hasOwnProperty('total') || operation.data.hasOwnProperty('avail');
},
when: 'after',
fn: async ({ operation }, context, option) => {
const { id, filter } = operation;
assert(typeof filter?.id === 'string');
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.accountNumberChanged}-${filter!.id!}`);
return 1;
},
} as UpdateTriggerInTxn<EntityDict, 'account', BRC>,
];
export default triggers;

View File

@ -4,11 +4,13 @@ import { BRC } from '@project/types/RuntimeCxt';
import aoTriggers from './accountOper';
import payTriggers from './pay';
import userSystemTriggers from './userSystem';
import accountTriggers from './acount';
const triggers = [
...aoTriggers,
...payTriggers,
...userSystemTriggers,
...accountTriggers,
] as Trigger<EntityDict, keyof EntityDict, BRC>[];
export default triggers;