修正了payConfig/upsert逻辑,修正了pay/detail的支付逻辑

This commit is contained in:
Xu Chang 2024-05-18 19:15:57 +08:00
parent a6fc6bb808
commit 12f9a83c96
21 changed files with 191 additions and 60 deletions

5
es/checkers/application.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { Checker } from 'oak-domain/lib/types/Auth';
import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from '../types/RuntimeCxt';
declare const checkers: Checker<EntityDict, 'application', RuntimeCxt>[];
export default checkers;

View File

@ -0,0 +1,31 @@
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 { OakInputIllegalException } from 'oak-domain/lib/types';
const checkers = [
{
type: 'data',
entity: 'application',
action: 'update',
checker: (data, context) => {
const { payConfig } = (data || {});
if (payConfig) {
const wechatPayConfigs = payConfig.filter(ele => [
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
].includes(ele.channel));
if (wechatPayConfigs) {
wechatPayConfigs.forEach((config) => {
const { apiV3Key } = config;
if (apiV3Key?.length && apiV3Key.length !== 32) {
throw new OakInputIllegalException('appliation', ['payConfig'], 'apiV3Key长度只能是32位');
}
});
}
}
return 1;
}
}
];
export default checkers;

View File

@ -1,9 +1,11 @@
import aoCheckers from './accountOper';
import payCheckers from './pay';
import orderCheckers from './order';
import applicationCheckers from './application';
const checkers = [
...aoCheckers,
...payCheckers,
...orderCheckers,
...applicationCheckers,
];
export default checkers;

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;
@ -46,7 +46,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;
opWidth?: number | undefined;
@ -58,14 +58,14 @@ declare const Detail: <T extends keyof EntityDict>(props: ReactComponentProps<En
data: Partial<EntityDict[T]["Schema"]>;
title?: string | undefined;
bordered?: boolean | undefined;
layout?: "vertical" | "horizontal" | undefined;
layout?: "horizontal" | "vertical" | undefined;
}>) => React.ReactElement;
declare const Upsert: <T extends keyof EntityDict>(props: ReactComponentProps<EntityDict, T, false, {
helps: Record<string, string>;
entity: T;
attributes: OakAbsAttrUpsertDef<EntityDict, T, string | number>[];
data: EntityDict[T]["Schema"];
layout: "vertical" | "horizontal";
layout: "horizontal" | "vertical";
mode: "default" | "card";
}>) => React.ReactElement;
export { FilterPanel, List, ListPro, Detail, Upsert, ReactComponentProps, ColumnProps, RowWithActions, OakExtraActionProps, OakAbsAttrDef, onActionFnDef, };

View File

@ -27,7 +27,7 @@ export function registerApplicationPayChannel(type, channel) {
}
}
export default function render(props) {
const { system, oakFullpath, operation, oakDirty, serverUrl } = props.data;
const { system, oakFullpath, operation, oakDirty, serverUrl, oakExecutable } = props.data;
const { t, update, setMessage, execute } = props.methods;
const defaultApplicationPayChannelDict = {
web: AppTypeToPayChannelDict.web.map(ele => [t(`payChannel::internal.${ele}`), ele]),
@ -39,7 +39,7 @@ export default function render(props) {
const { payConfig, application$system: applications } = system;
return (<div className={Styles.container}>
<Row justify="end" style={{ marginBottom: 12 }}>
<Button type="primary" disabled={!oakDirty} onClick={() => execute()}>
<Button type="primary" disabled={!oakDirty && oakExecutable !== true} onClick={() => execute()}>
{t('common::action.save')}
</Button>
</Row>

View File

@ -25,18 +25,18 @@ export default function WechatPay(props) {
<Input prefix={`${serverUrl}/endpoint`} suffix='/${payId}' value={config.payNotifyUrl} placeholder={t('placeholder.payNotifyUrl')} onChange={({ currentTarget }) => {
config.payNotifyUrl = currentTarget.value;
update(config);
}}/>
</Form.Item>
<Form.Item label={t('label.apiV3Key')}>
<Input value={config.apiV3Key} placeholder={t('placeholder.apiV3Key')} onChange={({ currentTarget }) => {
config.apiV3Key = currentTarget.value;
update(config);
}}/>
</Form.Item>
<Form.Item label={t('label.refundNotifyUrl')}>
<Input prefix={`${serverUrl}/endpoint`} suffix='/${refundId}' value={config.refundNotifyUrl} placeholder={t('placeholder.refundNotifyUrl')} onChange={({ currentTarget }) => {
config.refundNotifyUrl = currentTarget.value;
update(config);
}}/>
</Form.Item>
<Form.Item label={t('label.apiV3Key')}>
<Input value={config.apiV3Key} placeholder={t('placeholder.apiV3Key')} onChange={({ currentTarget }) => {
config.apiV3Key = currentTarget.value;
update(config);
}}/>
</Form.Item>
<Form.Item label={t('label.lossRatio')} help={t('placeholder.lossRatio')}>

View File

@ -8,11 +8,11 @@
"apiV3Key": "apiV3Key"
},
"placeholder": {
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限",
"privateKeyFilePath": "服务器上存放apiclient_key.pem的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放apiclient_cert.pem的路径,注意访问权限",
"lossRatio": "填百分比(0.6就代表千分之六)",
"payNotifyUrl": "填写回调的endpoint",
"refundNotifyUrl": "填写回调endpoint",
"payNotifyUrl": "endpoint",
"refundNotifyUrl": "endpoint",
"apiV3Key": "需要登录商户后台获取"
}
}

View File

@ -224,11 +224,11 @@ const i18ns = [
"apiV3Key": "apiV3Key"
},
"placeholder": {
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限",
"privateKeyFilePath": "服务器上存放apiclient_key.pem的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放apiclient_cert.pem的路径,注意访问权限",
"lossRatio": "填百分比(0.6就代表千分之六)",
"payNotifyUrl": "填写回调的endpoint",
"refundNotifyUrl": "填写回调endpoint",
"payNotifyUrl": "endpoint",
"refundNotifyUrl": "endpoint",
"apiV3Key": "需要登录商户后台获取"
}
}

5
lib/checkers/application.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
import { Checker } from 'oak-domain/lib/types/Auth';
import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from '../types/RuntimeCxt';
declare const checkers: Checker<EntityDict, 'application', RuntimeCxt>[];
export default checkers;

View File

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const PayConfig_1 = require("../types/PayConfig");
const types_1 = require("oak-domain/lib/types");
const checkers = [
{
type: 'data',
entity: 'application',
action: 'update',
checker: (data, context) => {
const { payConfig } = (data || {});
if (payConfig) {
const wechatPayConfigs = payConfig.filter(ele => [
PayConfig_1.PAY_CHANNEL_WECHAT_APP_NAME,
PayConfig_1.PAY_CHANNEL_WECHAT_H5_NAME,
PayConfig_1.PAY_CHANNEL_WECHAT_JS_NAME,
PayConfig_1.PAY_CHANNEL_WECHAT_MP_NAME,
PayConfig_1.PAY_CHANNEL_WECHAT_NATIVE_NAME
].includes(ele.channel));
if (wechatPayConfigs) {
wechatPayConfigs.forEach((config) => {
const { apiV3Key } = config;
if (apiV3Key?.length && apiV3Key.length !== 32) {
throw new types_1.OakInputIllegalException('appliation', ['payConfig'], 'apiV3Key长度只能是32位');
}
});
}
}
return 1;
}
}
];
exports.default = checkers;

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 order_1 = tslib_1.__importDefault(require("./order"));
const application_1 = tslib_1.__importDefault(require("./application"));
const checkers = [
...accountOper_1.default,
...pay_1.default,
...order_1.default,
...application_1.default,
];
exports.default = checkers;

View File

@ -226,11 +226,11 @@ const i18ns = [
"apiV3Key": "apiV3Key"
},
"placeholder": {
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限",
"privateKeyFilePath": "服务器上存放apiclient_key.pem的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放apiclient_cert.pem的路径,注意访问权限",
"lossRatio": "填百分比(0.6就代表千分之六)",
"payNotifyUrl": "填写回调的endpoint",
"refundNotifyUrl": "填写回调endpoint",
"payNotifyUrl": "endpoint",
"refundNotifyUrl": "endpoint",
"apiV3Key": "需要登录商户后台获取"
}
}

View File

@ -0,0 +1,41 @@
import { Checker } from 'oak-domain/lib/types/Auth';
import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from '../types/RuntimeCxt';
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, WechatPayConfig } from '@project/types/PayConfig';
import { OakInputIllegalException } from 'oak-domain/lib/types';
const checkers: Checker<EntityDict, 'application', RuntimeCxt>[] = [
{
type: 'data',
entity: 'application',
action: 'update',
checker: (data, context) => {
const { payConfig } = (data || {}) as EntityDict['application']['Update']['data'];
if (payConfig) {
const wechatPayConfigs = payConfig.filter(
ele => [
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
].includes(ele.channel)
);
if (wechatPayConfigs) {
wechatPayConfigs.forEach(
(config) => {
const { apiV3Key } = config as WechatPayConfig;
if (apiV3Key?.length && apiV3Key.length !== 32) {
throw new OakInputIllegalException('appliation', ['payConfig'], 'apiV3Key长度只能是32位');
}
}
)
}
}
return 1;
}
}
];
export default checkers;

View File

@ -4,11 +4,13 @@ import { RuntimeCxt } from '../types/RuntimeCxt';
import aoCheckers from './accountOper';
import payCheckers from './pay';
import orderCheckers from './order';
import applicationCheckers from './application';
const checkers = [
...aoCheckers,
...payCheckers,
...orderCheckers,
...applicationCheckers,
] as Checker<EntityDict, keyof EntityDict, RuntimeCxt>[];
export default checkers;

View File

@ -131,8 +131,16 @@ export default OakComponent({
switch (channel) {
case PAY_CHANNEL_WECHAT_MP_NAME: {
const { prepayMeta } = meta as { prepayMeta: WechatMiniprogram.RequestPaymentOption };
const result = await wx.requestPayment(prepayMeta);
console.log(result);
if (prepayMeta) {
const result = await wx.requestPayment(prepayMeta);
console.log(result);
}
else {
this.setMessage({
type: 'warning',
content: '没有预支付数据,可能是在开发环境,请检查',
});
}
break;
}
default: {

View File

@ -85,7 +85,18 @@
</view>
<view class="padding" />
<view class="btn-container">
<block wx:if="{{oakExecutable === true}}">
<block wx:if="{{startPayable}}">
<view class="btn">
<l-button
type="default"
size="long"
bind:lintap="startPay"
>
{{t('pay')}}
</l-button>
</view>
</block>
<block wx:elif="{{oakExecutable === true}}">
<view class="btn">
<l-button
type="default"
@ -125,17 +136,6 @@
bind:lintap="cancelCloseMp"
/>
</block>
<block wx:elif="{{startPayable}}">
<view class="btn">
<l-button
type="default"
size="long"
bind:lintap="startPay"
>
{{t('pay')}}
</l-button>
</view>
</block>
<block wx:else>
<view class="btn">
<l-button

View File

@ -29,5 +29,6 @@
"account": "帐户充值"
},
"success": "支付成功",
"pay": "支付"
"pay": "支付",
"wechatPay": "微信支付"
}

View File

@ -42,7 +42,7 @@ export default function render(props: WebComponentProps<EntityDict, 'system', fa
operation?: EntityDict['system']['Update'];
serverUrl?: string;
}>) {
const { system, oakFullpath, operation, oakDirty, serverUrl } = props.data;
const { system, oakFullpath, operation, oakDirty, serverUrl, oakExecutable } = props.data;
const { t, update, setMessage, execute } = props.methods;
const defaultApplicationPayChannelDict: {
@ -62,7 +62,7 @@ export default function render(props: WebComponentProps<EntityDict, 'system', fa
<Row justify="end" style={{ marginBottom: 12 }}>
<Button
type="primary"
disabled={!oakDirty}
disabled={!oakDirty && oakExecutable !== true}
onClick={() => execute()}
>
{t('common::action.save')}

View File

@ -57,16 +57,6 @@ export default function WechatPay(props: {
}}
/>
</Form.Item>
<Form.Item label={t('label.apiV3Key')}>
<Input
value={config.apiV3Key}
placeholder={t('placeholder.apiV3Key')}
onChange={({ currentTarget }) => {
config.apiV3Key = currentTarget.value;
update(config);
}}
/>
</Form.Item>
<Form.Item label={t('label.refundNotifyUrl')}>
<Input
prefix={`${serverUrl}/endpoint`}
@ -79,6 +69,16 @@ export default function WechatPay(props: {
}}
/>
</Form.Item>
<Form.Item label={t('label.apiV3Key')}>
<Input
value={config.apiV3Key}
placeholder={t('placeholder.apiV3Key')}
onChange={({ currentTarget }) => {
config.apiV3Key = currentTarget.value;
update(config);
}}
/>
</Form.Item>
<Form.Item
label={t('label.lossRatio')}
help={t('placeholder.lossRatio')}

View File

@ -8,11 +8,11 @@
"apiV3Key": "apiV3Key"
},
"placeholder": {
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限",
"privateKeyFilePath": "服务器上存放apiclient_key.pem的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放apiclient_cert.pem的路径,注意访问权限",
"lossRatio": "填百分比(0.6就代表千分之六)",
"payNotifyUrl": "填写回调的endpoint",
"refundNotifyUrl": "填写回调endpoint",
"payNotifyUrl": "endpoint",
"refundNotifyUrl": "endpoint",
"apiV3Key": "需要登录商户后台获取"
}
}

View File

@ -121,7 +121,8 @@ const i18ns: I18n[] = [
"account": "帐户充值"
},
"success": "支付成功",
"pay": "支付"
"pay": "支付",
"wechatPay": "微信支付"
}
},
{
@ -226,11 +227,11 @@ const i18ns: I18n[] = [
"apiV3Key": "apiV3Key"
},
"placeholder": {
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限",
"privateKeyFilePath": "服务器上存放apiclient_key.pem的路径,注意访问权限",
"publicKeyFilePath": "服务器上存放apiclient_cert.pem的路径,注意访问权限",
"lossRatio": "填百分比(0.6就代表千分之六)",
"payNotifyUrl": "填写回调的endpoint",
"refundNotifyUrl": "填写回调endpoint",
"payNotifyUrl": "endpoint",
"refundNotifyUrl": "endpoint",
"apiV3Key": "需要登录商户后台获取"
}
}