| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- import { useCallback } from 'react';
- import { Trans, useTranslation } from 'react-i18next';
- import LoginForm from '@/components/LoginForm';
- import { message } from '@/config/request/antdAppInstance';
- import { PayUrlShowType } from '@/defines';
- import { useAppUrls } from '@/hooks/useAppUrls';
- import { dialogModel } from '@/models/dialogModel';
- import { fetchGetUserConfig, fetchPayOrderCreate } from '@/services/config';
- import { getToken } from '@/utils/authUtils';
- import { currentUnixTimestamp } from '@/utils/timeUtils';
- import { PayQrContent } from './components/OrderSummary/PayQrContent';
- import { PayWaitingContent } from './components/OrderSummary/PayWaitingContent';
- import type { Plan } from './useService';
- const ORDER_TYPE_PLAN = 1;
- type PayOrder = { orderId: string; payUrl: string; showType: PayUrlShowType };
- export interface UseActionReturn {
- handlePayNow: (plan: Plan, payMethod: string) => void;
- }
- function useLoginDialog() {
- const { t } = useTranslation();
- const { openDialog, closeDialog } = dialogModel.useModel();
- const { deeplinkUrl, downloadUrlByPlatform } = useAppUrls();
- return useCallback(() => {
- const id = openDialog({
- title: t('pages.pricing.payFlow.loginTitle'),
- content: (
- <div className="flex flex-col gap-2">
- <p className="text-white/80 text-sm mb-2">
- <Trans
- i18nKey="pages.pricing.payFlow.loginPrompt"
- components={{
- linkText: (() => {
- const Wrap = ({ children }: { children?: React.ReactNode }) =>
- deeplinkUrl ? (
- <a
- href={deeplinkUrl}
- className="text-[#0EA5E9] hover:underline"
- target="_blank"
- rel="noopener noreferrer"
- >
- {children}
- </a>
- ) : (
- <span>{children}</span>
- );
- return <Wrap />;
- })(),
- downloadLink: (() => {
- const Wrap = ({ children }: { children?: React.ReactNode }) =>
- downloadUrlByPlatform ? (
- <a
- href={downloadUrlByPlatform}
- className="text-[#0EA5E9] hover:underline"
- target="_blank"
- rel="noopener noreferrer"
- >
- {children}
- </a>
- ) : (
- <span>{children}</span>
- );
- return <Wrap />;
- })(),
- }}
- />
- </p>
- <LoginForm onSuccess={() => closeDialog(id)} />
- </div>
- ),
- maskClosable: false,
- closeable: true,
- });
- }, [t, openDialog, closeDialog, deeplinkUrl, downloadUrlByPlatform]);
- }
- function useQrPayDialog() {
- const { t } = useTranslation();
- const { openDialog, closeDialog } = dialogModel.useModel();
- const onPaymentSuccess = useCallback(() => {
- return fetchGetUserConfig({}).then(() => {
- message.success(t('pages.pricing.payFlow.planPurchaseSuccess'));
- });
- }, [t]);
- return useCallback(
- (order: PayOrder) => {
- const qrDialogId = openDialog({
- title: t('pages.pricing.payFlow.waitingTitle'),
- content: (
- <PayQrContent
- orderId={order.orderId}
- payUrl={order.payUrl}
- onClose={() => closeDialog(qrDialogId)}
- onPaymentSuccess={onPaymentSuccess}
- />
- ),
- buttons: [
- {
- label: t('pages.pricing.payFlow.closeWaiting'),
- variant: 'secondary' as const,
- onClick: (_e: React.MouseEvent<HTMLButtonElement>, dialogId: string) => {
- closeDialog(dialogId);
- },
- },
- ],
- maskClosable: false,
- closeable: true,
- });
- },
- [t, openDialog, closeDialog, onPaymentSuccess]
- );
- }
- function useJumpToPayDialog() {
- const { t } = useTranslation();
- const { openDialog, closeDialog } = dialogModel.useModel();
- const onPaymentSuccess = useCallback(() => {
- return fetchGetUserConfig({}).then(() => {
- message.success(t('pages.pricing.payFlow.planPurchaseSuccess'));
- });
- }, [t]);
- return useCallback(
- (order: PayOrder) => {
- openDialog({
- title: t('pages.pricing.payFlow.goToPayTitle'),
- content: (
- <p className="text-white/90 text-sm leading-[1.43]">
- {t('pages.pricing.payFlow.goToPayDesc')}
- </p>
- ),
- buttons: [
- {
- label: t('pages.pricing.payFlow.goToPayButton'),
- variant: 'primary' as const,
- onClick: (_e: React.MouseEvent<HTMLButtonElement>, dialogId: string) => {
- window.open(order.payUrl, '_blank');
- closeDialog(dialogId);
- const waitId = openDialog({
- title: t('pages.pricing.payFlow.waitingTitle'),
- content: (
- <PayWaitingContent
- orderId={order.orderId}
- onClose={() => closeDialog(waitId)}
- onPaymentSuccess={onPaymentSuccess}
- />
- ),
- buttons: [
- {
- label: t('pages.pricing.payFlow.closeWaiting'),
- variant: 'secondary' as const,
- onClick: (
- _e: React.MouseEvent<HTMLButtonElement>,
- d: string
- ) => {
- closeDialog(d);
- },
- },
- ],
- maskClosable: false,
- });
- },
- },
- ],
- maskClosable: false,
- closeable: true,
- });
- },
- [t, openDialog, closeDialog, onPaymentSuccess]
- );
- }
- export function useAction(): UseActionReturn {
- const openLoginDialog = useLoginDialog();
- const openQrPayDialog = useQrPayDialog();
- const openJumpToPayDialog = useJumpToPayDialog();
- const handlePayNow = useCallback(
- (selectedPlan: Plan, selectedPayMethod: string) => {
- const token = getToken();
- const expired =
- !token?.accessExpires || (token.accessExpires ?? 0) - currentUnixTimestamp() <= 0;
- if (!token?.accessToken || expired) {
- // 如果用户未登录,则打开登录对话框
- openLoginDialog();
- return;
- }
- // 创建订单
- fetchPayOrderCreate({
- orderType: ORDER_TYPE_PLAN,
- payType: selectedPayMethod,
- channelItemId: selectedPlan.id,
- })
- .then((res) => {
- const order = res?.data?.userPayOrder;
- if (!order?.payUrl || !order?.orderId) return;
- if (order.showType === PayUrlShowType.SHOW_QR_CODE) {
- // 如果订单支付地址的显示类型为二维码,则打开二维码支付对话框
- openQrPayDialog(order);
- return;
- }
- // 如果订单支付地址的显示类型为跳转,则跳转到支付地址并打开等待支付对话框
- openJumpToPayDialog(order);
- })
- .catch(() => {});
- },
- [openLoginDialog, openQrPayDialog, openJumpToPayDialog]
- );
- return {
- handlePayNow,
- };
- }
|