完善了payDetail

This commit is contained in:
Xu Chang 2024-05-12 23:45:34 +08:00
parent 0e674ea63d
commit fdd12e126d
40 changed files with 185 additions and 54 deletions

View File

@ -20,7 +20,7 @@ declare const List: <T extends keyof EntityDict>(props: ReactComponentProps<Enti
rowSelection?: any;
hideHeader?: boolean | undefined;
disableSerialNumber?: boolean | undefined;
size?: "small" | "middle" | "large" | undefined;
size?: "small" | "large" | "middle" | undefined;
scroll?: ({
x?: string | number | true | undefined;
y?: string | number | undefined;
@ -45,7 +45,7 @@ declare const ListPro: <T extends keyof EntityDict>(props: {
tablePagination?: any;
rowSelection?: any;
disableSerialNumber?: boolean | undefined;
size?: "small" | "middle" | "large" | undefined;
size?: "small" | "large" | "middle" | undefined;
scroll?: any;
locale?: any;
}) => React.ReactElement;

View File

@ -2,5 +2,5 @@
"label": {
"option": "渠道"
},
"onChannel": "未配置收费渠道"
"noChannel": "未配置收费渠道"
}

View File

@ -1,5 +1,7 @@
import { CentToString } from "oak-domain/lib/utils/money";
import { PAY_CHANNEL_OFFLINE_NAME, PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_WECHAT_APP_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME } from "../../../types/PayConfig";
import { DATA_SUBSCRIBER_KEYS } from "../../../config/constants";
import assert from "assert";
export default OakComponent({
entity: 'pay',
isList: false,
@ -110,5 +112,17 @@ export default OakComponent({
goBack() {
this.navigateBack();
}
},
lifetimes: {
ready() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`]);
},
detached() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.unsubDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`]);
}
}
});

View File

@ -55,8 +55,8 @@ function RenderWechatPay(props) {
const { externalId, channel, timeoutAt, iState } = pay;
if (iState === 'paid') {
return (<div className={Styles.paid}>
<CheckCircleOutline fontSize={36} fontWeight="bold" color="green"/>
<div className='text'>
<CheckCircleOutline fontSize={72} fontWeight="bold" color="green"/>
<div className={Styles.text}>
{t('success')}
</div>
</div>);

View File

@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Input, Tag, Card, QRCode, Form, Descriptions, Typography, Alert, Select, Button, Modal } from 'antd';
import { CheckCircleOutlined } from '@ant-design/icons';
import { CentToString } from 'oak-domain/lib/utils/money';
import Styles from './web.pc.module.less';
import * as dayJs from 'dayjs';
@ -51,6 +52,18 @@ function Counter(props) {
function RenderWechatPay(props) {
const { pay, t } = props;
const { externalId, channel, timeoutAt, iState } = pay;
if (iState === 'paid') {
return (<div className={Styles.paid}>
<CheckCircleOutlined style={{
fontSize: 72,
color: 'green',
fontWeight: 'bold',
}}/>
<div className={Styles.text}>
{t('success')}
</div>
</div>);
}
switch (channel) {
case PAY_CHANNEL_WECHAT_NATIVE_NAME: {
if (iState === 'paying') {

View File

@ -13,6 +13,22 @@
}
}
.paid {
margin-top: 10px;
margin-bottom: 15px;
display: flex;
flex-direction: column;
align-items: center;
.text {
margin-top: 8px;
font-size: 26px;
font-weight: bold;
color: green;
}
}
.oper {
margin-top: 40px;
width: 60%;

View File

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

View File

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

View File

@ -70,7 +70,7 @@ const i18ns = [
"label": {
"option": "渠道"
},
"onChannel": "未配置收费渠道"
"noChannel": "未配置收费渠道"
}
},
{

View File

@ -3,6 +3,7 @@ import assert from 'assert';
import { getPayClazz } from '../utils/payClazz';
import { fullPayProjection } from '../utils/pay';
import { PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_OFFLINE_NAME } from '../types/PayConfig';
import { DATA_SUBSCRIBER_KEYS } from '../config/constants';
async function changeOrderStateByPay(filter, context, option) {
const orders = await context.select('order', {
data: {
@ -200,13 +201,13 @@ const triggers = [
},
},
{
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态',
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态,同时尝试向订阅者推送',
entity: 'pay',
action: ['startPaying', 'succeedPaying', 'startClosing', 'succeedClosing', 'startRefunding',
'refundAll', 'refundPartially'],
when: 'after',
fn: async ({ operation }, context, option) => {
const { filter, action } = operation;
const { filter, action, id } = operation;
assert(typeof filter.id === 'string');
const [pay] = await context.select('pay', {
data: {
@ -218,6 +219,7 @@ const triggers = [
filter,
}, { dontCollect: true });
const { orderId, accountId } = pay;
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.payStateChanged}-${filter.id}`);
if (orderId) {
return await changeOrderStateByPay({ id: orderId }, context, option);
}
@ -271,6 +273,7 @@ const triggers = [
entity: 'pay',
action: ['close'],
when: 'before',
priority: 99,
fn: async ({ operation }, context, option) => {
const { data, filter } = operation;
const pays = await context.select('pay', {

View File

@ -1,8 +1,8 @@
import { EntityDict } from '../oak-app-domain';
import { SelectOpResult } from 'oak-domain/lib/types/Entity';
import { OpRecord } from 'oak-domain/lib/types/Entity';
export default function makeException<ED extends EntityDict>(data: {
name: string;
message?: string;
opRecords: SelectOpResult<ED>;
opRecords: OpRecord<ED>[];
[A: string]: any;
}): import("oak-domain/lib/types/Exception").OakException<ED> | undefined;

View File

@ -1,7 +1,7 @@
import { OpSchema, UpdateOperationData } from "../../oak-app-domain/Pay/Schema";
import PayClazz from "../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../types/PayConfig";
import { BRC } from "../../types/RuntimeCxt";
import { OpSchema, UpdateOperationData } from "../../../oak-app-domain/Pay/Schema";
import PayClazz from "../../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../../types/PayConfig";
import { BRC } from "../../../types/RuntimeCxt";
export default class WechatPay implements PayClazz {
channel: string;
constructor(channel: WechatPayChannel, appId: string, config: WechatPayConfig);

View File

@ -1,8 +1,8 @@
import { EntityDict } from "../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../oak-app-domain/Pay/Schema";
import PayClazz from "../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../types/PayConfig";
import { BRC } from "../../types/RuntimeCxt";
import { EntityDict } from "../../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../../oak-app-domain/Pay/Schema";
import PayClazz from "../../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../../types/PayConfig";
import { BRC } from "../../../types/RuntimeCxt";
export declare function registerGetPayStateResult(payState: NonNullable<EntityDict['pay']['OpSchema']['iState']>): void;
export default class WechatPay implements PayClazz {
channel: string;

View File

@ -1,4 +1,4 @@
import { PAY_CHANNEL_WECHAT_APP_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME } from "../../types/PayConfig";
import { PAY_CHANNEL_WECHAT_APP_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME } from "../../../types/PayConfig";
let _PAY_STATE = '';
export function registerGetPayStateResult(payState) {
_PAY_STATE = payState;

View File

@ -0,0 +1,3 @@
import WechatPay from './WechatPay';
declare const _default: typeof WechatPay;
export default _default;

View File

@ -0,0 +1,4 @@
import WechatPay from './WechatPay';
import WechatPayDebug from './WechatPay.debug';
// 微信支付没有沙箱环境所以staging模式也只能用debug
export default process.env.NODE_ENV === 'production' ? WechatPay : WechatPayDebug;

View File

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

View File

@ -1,4 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DATA_SUBSCRIBER_KEYS = void 0;
exports.DATA_SUBSCRIBER_KEYS = {};
exports.DATA_SUBSCRIBER_KEYS = {
payStateChanged: 'oak-pay-business-psc',
};

View File

@ -72,7 +72,7 @@ const i18ns = [
"label": {
"option": "渠道"
},
"onChannel": "未配置收费渠道"
"noChannel": "未配置收费渠道"
}
},
{

View File

@ -6,6 +6,7 @@ const assert_1 = tslib_1.__importDefault(require("assert"));
const payClazz_1 = require("../utils/payClazz");
const pay_1 = require("../utils/pay");
const PayConfig_1 = require("../types/PayConfig");
const constants_1 = require("../config/constants");
async function changeOrderStateByPay(filter, context, option) {
const orders = await context.select('order', {
data: {
@ -203,13 +204,13 @@ const triggers = [
},
},
{
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态',
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态,同时尝试向订阅者推送',
entity: 'pay',
action: ['startPaying', 'succeedPaying', 'startClosing', 'succeedClosing', 'startRefunding',
'refundAll', 'refundPartially'],
when: 'after',
fn: async ({ operation }, context, option) => {
const { filter, action } = operation;
const { filter, action, id } = operation;
(0, assert_1.default)(typeof filter.id === 'string');
const [pay] = await context.select('pay', {
data: {
@ -221,6 +222,7 @@ const triggers = [
filter,
}, { dontCollect: true });
const { orderId, accountId } = pay;
context.saveOperationToEvent(id, `${constants_1.DATA_SUBSCRIBER_KEYS.payStateChanged}-${filter.id}`);
if (orderId) {
return await changeOrderStateByPay({ id: orderId }, context, option);
}
@ -274,6 +276,7 @@ const triggers = [
entity: 'pay',
action: ['close'],
when: 'before',
priority: 99,
fn: async ({ operation }, context, option) => {
const { data, filter } = operation;
const pays = await context.select('pay', {

View File

@ -1,8 +1,8 @@
import { EntityDict } from '../oak-app-domain';
import { SelectOpResult } from 'oak-domain/lib/types/Entity';
import { OpRecord } from 'oak-domain/lib/types/Entity';
export default function makeException<ED extends EntityDict>(data: {
name: string;
message?: string;
opRecords: SelectOpResult<ED>;
opRecords: OpRecord<ED>[];
[A: string]: any;
}): import("oak-domain/lib/types/Exception").OakException<ED> | undefined;

View File

@ -1,7 +1,7 @@
import { OpSchema, UpdateOperationData } from "../../oak-app-domain/Pay/Schema";
import PayClazz from "../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../types/PayConfig";
import { BRC } from "../../types/RuntimeCxt";
import { OpSchema, UpdateOperationData } from "../../../oak-app-domain/Pay/Schema";
import PayClazz from "../../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../../types/PayConfig";
import { BRC } from "../../../types/RuntimeCxt";
export default class WechatPay implements PayClazz {
channel: string;
constructor(channel: WechatPayChannel, appId: string, config: WechatPayConfig);

View File

@ -1,8 +1,8 @@
import { EntityDict } from "../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../oak-app-domain/Pay/Schema";
import PayClazz from "../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../types/PayConfig";
import { BRC } from "../../types/RuntimeCxt";
import { EntityDict } from "../../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../../oak-app-domain/Pay/Schema";
import PayClazz from "../../../types/PayClazz";
import { WechatPayChannel, WechatPayConfig } from "../../../types/PayConfig";
import { BRC } from "../../../types/RuntimeCxt";
export declare function registerGetPayStateResult(payState: NonNullable<EntityDict['pay']['OpSchema']['iState']>): void;
export default class WechatPay implements PayClazz {
channel: string;

View File

@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerGetPayStateResult = void 0;
const PayConfig_1 = require("../../types/PayConfig");
const PayConfig_1 = require("../../../types/PayConfig");
let _PAY_STATE = '';
function registerGetPayStateResult(payState) {
_PAY_STATE = payState;

View File

@ -0,0 +1,3 @@
import WechatPay from './WechatPay';
declare const _default: typeof WechatPay;
export default _default;

View File

@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const WechatPay_1 = tslib_1.__importDefault(require("./WechatPay"));
const WechatPay_debug_1 = tslib_1.__importDefault(require("./WechatPay.debug"));
// 微信支付没有沙箱环境所以staging模式也只能用debug
console.log('WechatPay', process.env.NODE_ENV);
exports.default = process.env.NODE_ENV === 'production' ? WechatPay_1.default : WechatPay_debug_1.default;

View File

@ -2,5 +2,5 @@
"label": {
"option": "渠道"
},
"onChannel": "未配置收费渠道"
"noChannel": "未配置收费渠道"
}

View File

@ -2,7 +2,8 @@ import { CentToString } from "oak-domain/lib/utils/money";
import { PAY_CHANNEL_OFFLINE_NAME, PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_WECHAT_APP_NAME,
PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME
} from "../../../types/PayConfig";
import { fullPayProjection } from "../../../utils/pay";
import { DATA_SUBSCRIBER_KEYS } from "../../../config/constants";
import assert from "assert";
export default OakComponent({
entity: 'pay',
@ -116,5 +117,17 @@ export default OakComponent({
goBack() {
this.navigateBack();
}
},
lifetimes: {
ready() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.subDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`]);
},
detached() {
const { oakId } = this.props;
assert(typeof oakId === 'string');
this.unsubDataEvents([`${DATA_SUBSCRIBER_KEYS.payStateChanged}-${oakId}`]);
}
}
});

View File

@ -13,6 +13,22 @@
}
}
.paid {
margin-top: 10px;
margin-bottom: 15px;
display: flex;
flex-direction: column;
align-items: center;
.text {
margin-top: 8px;
font-size: 26px;
font-weight: bold;
color: green;
}
}
.oper {
margin-top: 40px;
width: 60%;

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Input, Space, Tag, Card, QRCode, Form, Descriptions, Typography, Alert, Select, Button, Modal } from 'antd';
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
import { CheckCircleOutlined } from '@ant-design/icons';
import { EntityDict } from '@project/oak-app-domain';
import { CentToString } from 'oak-domain/lib/utils/money';
import Styles from './web.pc.module.less';
@ -92,6 +93,22 @@ function RenderWechatPay(props: {
}) {
const { pay, t } = props;
const { externalId, channel, timeoutAt, iState } = pay;
if (iState === 'paid') {
return (
<div className={Styles.paid}>
<CheckCircleOutlined
style={{
fontSize: 72,
color: 'green',
fontWeight: 'bold',
}}
/>
<div className={Styles.text}>
{t('success')}
</div>
</div>
);
}
switch (channel) {
case PAY_CHANNEL_WECHAT_NATIVE_NAME: {
if (iState! === 'paying') {

View File

@ -101,11 +101,11 @@ function RenderWechatPay(props: {
return (
<div className={Styles.paid}>
<CheckCircleOutline
fontSize={36}
fontSize={72}
fontWeight="bold"
color="green"
/>
<div className='text'>
<div className={Styles.text}>
{t('success')}
</div>
</div>

View File

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

View File

@ -72,7 +72,7 @@ const i18ns: I18n[] = [
"label": {
"option": "渠道"
},
"onChannel": "未配置收费渠道"
"noChannel": "未配置收费渠道"
}
},
{

View File

@ -7,6 +7,7 @@ import { OperateOption } from 'oak-domain/lib/types';
import { getPayClazz } from '@project/utils/payClazz';
import { fullPayProjection } from '@project/utils/pay';
import { PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_OFFLINE_NAME } from '@project/types/PayConfig';
import { DATA_SUBSCRIBER_KEYS } from '@project/config/constants';
async function changeOrderStateByPay(
filter: NonNullable<EntityDict['order']['Update']['filter']>,
@ -216,13 +217,13 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
},
} as CreateTriggerInTxn<EntityDict, 'pay', BRC>,
{
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态',
name: '当pay的状态发生变化时修改相应的order的状态或者account的状态,同时尝试向订阅者推送',
entity: 'pay',
action: ['startPaying', 'succeedPaying', 'startClosing', 'succeedClosing', 'startRefunding',
'refundAll', 'refundPartially'],
when: 'after',
fn: async ({ operation }, context, option) => {
const { filter, action } = operation as EntityDict['pay']['Update'];
const { filter, action, id } = operation as EntityDict['pay']['Update'];
assert(typeof filter!.id === 'string');
const [pay] = await context.select('pay', {
@ -236,6 +237,7 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
}, { dontCollect: true });
const { orderId, accountId } = pay;
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.payStateChanged}-${filter!.id!}`);
if (orderId) {
return await changeOrderStateByPay({ id: orderId }, context, option);
}
@ -290,6 +292,7 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
entity: 'pay',
action: ['close'],
when: 'before',
priority: 99,
fn: async ({ operation }, context, option) => {
const { data, filter } = operation;
const pays = await context.select('pay', {

View File

@ -1,11 +1,11 @@
import { EntityDict } from '@project/oak-app-domain';
import { SelectOpResult } from 'oak-domain/lib/types/Entity';
import { SelectOpResult, OpRecord } from 'oak-domain/lib/types/Entity';
import { makeException as makeDomainException } from 'oak-domain/lib/types/Exception';
import { makeException as makeOgb0Exception } from "oak-general-business";
export default function makeException<ED extends EntityDict>(data: {
name: string;
message?: string;
opRecords: SelectOpResult<ED>;
opRecords: OpRecord<ED>[];
[A: string]: any;
}) {
const e = makeDomainException<ED>(data) || makeOgb0Exception<ED>(data);

View File

@ -1,9 +1,9 @@
import { EntityDict } from "../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../oak-app-domain/Pay/Schema";
import PayClazz from "../../types/PayClazz";
import { EntityDict } from "../../../oak-app-domain";
import { OpSchema, UpdateOperationData } from "../../../oak-app-domain/Pay/Schema";
import PayClazz from "../../../types/PayClazz";
import { PAY_CHANNEL_ACCOUNT_NAME, PAY_CHANNEL_WECHAT_APP_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_JS_NAME,
PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME, WechatPayChannel, WechatPayConfig } from "../../types/PayConfig";
import { BRC } from "../../types/RuntimeCxt";
PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME, WechatPayChannel, WechatPayConfig } from "../../../types/PayConfig";
import { BRC } from "../../../types/RuntimeCxt";
let _PAY_STATE = '';
export function registerGetPayStateResult(payState: NonNullable<EntityDict['pay']['OpSchema']['iState']>) {

View File

@ -0,0 +1,5 @@
import WechatPay from './WechatPay';
import WechatPayDebug from './WechatPay.debug';
// 微信支付没有沙箱环境所以staging模式也只能用debug
export default process.env.NODE_ENV === 'production' ? WechatPay : WechatPayDebug;