Commit 02da6483 authored by Bill's avatar Bill

feat: 对接结算通联支付

parent 30fea125
/**
* 通联支付 - 微信支付 11
*/
export const UNIVERSAL_PAY_WECHAT = 11
/**
* 通联支付 - 支付宝支付 12
*/
export const UNIVERSAL_PAY_ALIPAY = 12
/**
* 通联支付 - 快捷支付 13
*/
export const UNIVERSAL_PAY_QUICK = 13
/**
* 通联支付 - 网银支付 14
*/
export const UNIVERSAL_PAY_UNION = 14
/**
* 通联支付 - 余额支付 15
*/
export const UNIVERSAL_PAY_BALANCE = 15
.container {
display: flex;
flex-direction: column;
.formItem {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 8px;
.input {
margin-right: 8px;
flex: 1;
}
}
.tips {
color: #91959B;
font-size: 12px;
margin-top: 8px;
}
}
import React, { useState } from 'react';
import { Button, Input, message, Modal } from 'antd';
import styles from './index.less'
import useCountDown from '@/utils/hooks';
import { getIntl } from 'umi';
import { getPayEAccountAllInPayReSendPayCode } from '@/services/PayV2Api';
const intl = getIntl()
interface Iprops {
visible: boolean,
title?: string,
onOk: (code: string) => void,
// onResendCode: () => void,
/** 商户订单号 */
tradeCode: string
}
const GetCodeModal: React.FC<Iprops> = (props: Iprops) => {
const { title = '验证码', onOk, visible, tradeCode } = props;
const [code, setCode] = useState<string>("");
const { text, isActive, start } = useCountDown({
maxTime: 60,
minTime: 0,
initText: intl.formatMessage({ id: 'payandSettle.eAccountApprove.components.personal.initText' }),
onEnd: () => { console.log("end") },
decayRate: 1,
delay: 1 * 1000
})
const handleOk = () => {
if(!code) {
message.error("请填写验证码");
return;
}
onOk?.(code)
}
const handleChange = (e) => {
setCode(e.target.value);
}
const handleSendCode = async () => {
const { code, data } = await getPayEAccountAllInPayReSendPayCode({
tradeCode: tradeCode
})
if (code === 1000) {
start();
}
}
return (
<Modal
visible={visible}
width={360}
title={title}
onOk={handleOk}
>
<div className={styles.container}>
<div className={styles.formItem}>
<div className={styles.input}>
<Input value={code} onChange={handleChange} />
</div>
<Button disabled={isActive} onClick={handleSendCode}>{text}</Button>
</div>
<div className={styles.tips}>已将验证码发送到您尾号为2800的手机号</div>
</div>
</Modal>
)
}
export default GetCodeModal
......@@ -36,9 +36,11 @@
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.item {
margin-right: 16px;
margin-bottom: 8px;
}
}
}
......
.tips {
display: flex;
flex-direction: row;
align-items: center;
font-size: 12px;
color: #252D37;
.modeImage {
width: 24px;
height: 24px;
}
}
.qrcode {
padding: 12px;
margin-top: 16px;
box-shadow: 0 0 6px 0 rgba(191,191,191,0.50);
img {
width: 210px;
height: 210px;
}
}
import { Modal } from 'antd';
import React from 'react';
import styles from './index.less'
import wechat from '@/assets/imgs/wechat_icon.png';
import alipay from '@/assets/imgs/alipay_icon.png';
interface Iprops {
mode: 'wechat' | 'alipay'
visible: boolean,
qrcode: string
}
const MODE_TEXT = {
wechat: '微信',
alipay: '支付宝'
}
const QrcodeModal: React.FC<Iprops> = (props: Iprops) => {
const { mode, visible, qrcode } = props;
const currentImage = mode === 'wechat' ? wechat : alipay;
return (
<Modal
visible={visible}
title={`请用${MODE_TEXT[mode]}支付`}
>
<div className={styles.tips}>
<img className={styles.modeImage} src={currentImage} />
<div>{`请打开${MODE_TEXT[mode]}扫一扫`}</div>
</div>
<div className={styles.qrcode}>
<img src={qrcode} />
</div>
</Modal>
)
}
export default QrcodeModal
......@@ -33,7 +33,11 @@ type ModalsType = {
/** 上传付款凭证 */
uploadPayVoucher: boolean,
/** 通联支付付款 */
universalPay: boolean
universalPay: boolean,
/** 二维码 */
qrcodeModal: boolean,
/** 获取短信验证码 */
smsCodeModal: boolean,
}
function useHandleSettlementList() {
......@@ -43,7 +47,9 @@ function useHandleSettlementList() {
viewUniversalPay: false,
manualSettlement: false,
uploadPayVoucher: false,
universalPay: false
universalPay: false,
qrcodeModal: false,
smsCodeModal: false,
})
......
import React, { useRef, useCallback, useEffect, useState, useMemo } from 'react';
import { useIntl } from 'umi'
import QRCode from 'qrcode';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Button, Card, DatePicker, Modal } from 'antd';
import { Button, Card, DatePicker, message, Modal } from 'antd';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions, FormEffectHooks } from '@formily/antd';
......@@ -19,6 +20,10 @@ import { postReportSettlementMemberManualSettlement } from '@/services/ReportV2A
import OtherPayModal from '../components/OtherPayModal';
import useHandleSettlementList from './hooks/useHandleSettlementList';
import ViewUniversalPay from '../../components/ViewUniversalPay';
import { UNIVERSAL_PAY_ALIPAY, UNIVERSAL_PAY_BALANCE, UNIVERSAL_PAY_QUICK, UNIVERSAL_PAY_UNION, UNIVERSAL_PAY_WECHAT } from '@/constants/universalPay';
import GetCodeModal from '../components/GetCodeModal';
import { postPayEAccountAllInPayConfirmPay } from '@/services/PayV2Api';
import QrcodeModal from '../components/QrcodeModal';
const { onFieldValueChange$ } = FormEffectHooks
const { RangePicker } = DatePicker;
......@@ -35,6 +40,8 @@ interface SearchParams {
pageSize: number,
}
/** 通联支付 11 => 微信, 12 支付宝 13 =》快捷支付 14 =》 网银支付 15 => 月支付 */
type UniversalPay = 11 | 12 | 13 | 14 | 15;
const SettlementList = () => {
const ref = useRef<any>({})
......@@ -42,8 +49,10 @@ const SettlementList = () => {
const { searchData, formatInitialValue, clear } = useSetSearchValueInTable();
const [uploadSubmitLoading, setUploadSubmitLoading] = useState<boolean>();
const [universalPayLoading, setUniversalPayLoading] = useState<boolean>(false)
const { itemInfo, modals, handleClose, columns } = useHandleSettlementList();
const { itemInfo, modals, handleClose, columns, handleOpen } = useHandleSettlementList();
const [files, setFiles] = useState([]);
const [qrcodeUrl, setQrcodeUrl] = useState<string>("");
const [currentUniversalPay, setCurrentUniversalPay] = useState<UniversalPay | null>(null);
const universalPayInfo1 = useMemo(() => ({
name: itemInfo?.settlementName,
......@@ -121,23 +130,76 @@ const SettlementList = () => {
}
}
const generateQrCode = async (codeUrl: string) => {
try {
const data = await QRCode.toDataURL(codeUrl);
setQrcodeUrl(data);
} catch(error) {
message.error(error)
}
}
/** 通联支付,短信验证码支付 */
const handleCompleteSmsCode = async (codeString: string) => {
const { code, data, message: msg } = await postPayEAccountAllInPayConfirmPay({
tradeCode: itemInfo.settlementNo,
verificationCode: codeString
})
if (code !== 1000) {
message.error(msg);
return;
}
handleClose('smsCodeModal');
}
/** 通联支付, 付款 */
const handleUniversalPay = async (params: {payChannel: number}) => {
const channel = params.payChannel;
try {
setUniversalPayLoading(true)
const { data, code } = await postSettleAccountsMemberSettlementCommunicationPay({
const { data, code, message: msg } = await postSettleAccountsMemberSettlementCommunicationPay({
id: itemInfo.id,
payChannelType: params.payChannel,
})
if (code === 1000) {
// handlePayModalClose();
handleClose('universalPay')
if (code !== 1000) {
message.error(msg);
return;
}
setCurrentUniversalPay(channel as UniversalPay);
if ([UNIVERSAL_PAY_WECHAT, UNIVERSAL_PAY_ALIPAY].includes(channel)) {
message.loading({
title: '正在生成支付二维码'
});
await generateQrCode(data);
handleClose('universalPay');
handleOpen('qrcodeModal');
return;
}
// 快捷支付 或者 余额支付
if (channel === UNIVERSAL_PAY_QUICK || channel === UNIVERSAL_PAY_BALANCE) {
handleClose('universalPay');
handleOpen('smsCodeModal')
// handleOpen()
return;
}
if (channel === UNIVERSAL_PAY_UNION) {
window.open(data);
}
} finally {
setUniversalPayLoading(true)
}
}
/** 轮询接口 */
useEffect(() => {
if (modals.qrcodeModal) {
}
}, [modals])
/**
* 搜索
*/
......@@ -217,6 +279,17 @@ const SettlementList = () => {
onClose={() => handleClose('viewUniversalPay')}
onOk={() => handleClose('viewUniversalPay')}
/>
<QrcodeModal
visible={true}
mode={currentUniversalPay === UNIVERSAL_PAY_WECHAT ? 'wechat' : 'alipay' }
// mode={'wechat'}
qrcode={qrcodeUrl}
/>
<GetCodeModal
visible={modals.smsCodeModal}
onOk={handleCompleteSmsCode}
tradeCode={itemInfo?.settlementNo}
/>
</PageHeaderWrapper>
)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment