useAction.tsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { useCallback } from 'react';
  2. import { Trans, useTranslation } from 'react-i18next';
  3. import LoginForm from '@/components/LoginForm';
  4. import { useAppUrls } from '@/hooks/useAppUrls';
  5. import { dialogModel } from '@/models/dialogModel';
  6. import { fetchPayOrderCreate } from '@/services/config';
  7. import { getToken } from '@/utils/authUtils';
  8. import { currentUnixTimestamp } from '@/utils/timeUtils';
  9. import { PayWaitingContent } from './PayWaitingContent';
  10. import type { Plan } from '../../useService';
  11. const ORDER_TYPE_PLAN = 1;
  12. export interface UseActionReturn {
  13. handlePayNow: () => void;
  14. }
  15. export interface UseActionParams {
  16. selectedPlan: Plan | null;
  17. selectedPayMethod: string | null;
  18. }
  19. export function useAction({ selectedPlan, selectedPayMethod }: UseActionParams): UseActionReturn {
  20. const { t } = useTranslation();
  21. const { openDialog, closeDialog } = dialogModel.useModel();
  22. const { deeplinkUrl, downloadUrlByPlatform } = useAppUrls();
  23. const handlePayNow = useCallback(() => {
  24. if (!selectedPlan || !selectedPayMethod) return;
  25. console.log('🚀 ~ useAction.tsx:30 ~ useAction ~ downloadUrlByPlatform:', downloadUrlByPlatform);
  26. console.log('🚀 ~ useAction.tsx:30 ~ useAction ~ deeplinkUrl:', deeplinkUrl);
  27. const token = getToken();
  28. const expired =
  29. !token?.accessExpires || (token.accessExpires ?? 0) - currentUnixTimestamp() <= 0;
  30. if (!token?.accessToken || expired) {
  31. const id = openDialog({
  32. title: t('pages.pricing.payFlow.loginTitle'),
  33. content: (
  34. <div className="flex flex-col gap-2">
  35. <p className="text-white/80 text-sm mb-2">
  36. <Trans
  37. i18nKey="pages.pricing.payFlow.loginPrompt"
  38. components={{
  39. linkText: (() => {
  40. const Wrap = ({
  41. children,
  42. }: {
  43. children?: React.ReactNode;
  44. }) =>
  45. deeplinkUrl ? (
  46. <a
  47. href={deeplinkUrl}
  48. className="text-[#0EA5E9] hover:underline"
  49. target="_blank"
  50. rel="noopener noreferrer"
  51. >
  52. {children}
  53. </a>
  54. ) : (
  55. <span>{children}</span>
  56. );
  57. return <Wrap />;
  58. })(),
  59. downloadLink: (() => {
  60. const Wrap = ({
  61. children,
  62. }: {
  63. children?: React.ReactNode;
  64. }) =>
  65. downloadUrlByPlatform ? (
  66. <a
  67. href={downloadUrlByPlatform}
  68. className="text-[#0EA5E9] hover:underline"
  69. target="_blank"
  70. rel="noopener noreferrer"
  71. >
  72. {children}
  73. </a>
  74. ) : (
  75. <span>{children}</span>
  76. );
  77. return <Wrap />;
  78. })(),
  79. }}
  80. />
  81. </p>
  82. <LoginForm onSuccess={() => closeDialog(id)} />
  83. </div>
  84. ),
  85. maskClosable: true,
  86. });
  87. return;
  88. }
  89. fetchPayOrderCreate({
  90. orderType: ORDER_TYPE_PLAN,
  91. payType: selectedPayMethod,
  92. channelItemId: selectedPlan.id,
  93. })
  94. .then((res) => {
  95. const order = res?.data?.userPayOrder;
  96. if (!order?.payUrl || !order?.orderId) return;
  97. openDialog({
  98. title: t('pages.pricing.payFlow.goToPayTitle'),
  99. content: (
  100. <p className="text-white/90 text-sm leading-[1.43]">
  101. {t('pages.pricing.payFlow.goToPayDesc')}
  102. </p>
  103. ),
  104. buttons: [
  105. {
  106. label: t('pages.pricing.payFlow.goToPayButton'),
  107. variant: 'primary',
  108. onClick: (
  109. _e: React.MouseEvent<HTMLButtonElement>,
  110. dialogId: string
  111. ) => {
  112. window.open(order.payUrl, '_blank');
  113. closeDialog(dialogId);
  114. const waitId = openDialog({
  115. title: t('pages.pricing.payFlow.waitingTitle'),
  116. content: (
  117. <PayWaitingContent
  118. orderId={order.orderId}
  119. onClose={() => closeDialog(waitId)}
  120. />
  121. ),
  122. buttons: [
  123. {
  124. label: t('pages.pricing.payFlow.closeWaiting'),
  125. variant: 'secondary',
  126. onClick: (
  127. _e: React.MouseEvent<HTMLButtonElement>,
  128. dialogId: string
  129. ) => {
  130. closeDialog(dialogId);
  131. },
  132. },
  133. ],
  134. maskClosable: false,
  135. });
  136. },
  137. },
  138. ],
  139. maskClosable: true,
  140. });
  141. })
  142. .catch(() => {});
  143. }, [
  144. selectedPlan,
  145. selectedPayMethod,
  146. t,
  147. openDialog,
  148. closeDialog,
  149. deeplinkUrl,
  150. downloadUrlByPlatform,
  151. ]);
  152. return {
  153. handlePayNow,
  154. };
  155. }