Jelajahi Sumber

feat: 从后端获取支持的支付方式列表

BaiLuoYan 3 bulan lalu
induk
melakukan
6f91d12d8a

+ 1 - 2
src/pages/pricing/components/OrderSummary/index.tsx

@@ -3,7 +3,6 @@ import { memo } from 'react';
 import { Button } from 'antd';
 import { useTranslation } from 'react-i18next';
 
-import type { PayMethodType } from '@/defines';
 import { useResponsive } from '@/hooks/useSize';
 
 import LabelValueItem from '../LabelValueItem';
@@ -13,7 +12,7 @@ import { useService } from './useService';
 
 export interface OrderSummaryProps {
     selectedPlan: Plan | null;
-    selectedPayMethod: PayMethodType | null;
+    selectedPayMethod: string | null;
 }
 
 const OrderSummary = memo(({ selectedPlan, selectedPayMethod }: OrderSummaryProps) => {

+ 1 - 3
src/pages/pricing/components/OrderSummary/useAction.ts

@@ -1,7 +1,5 @@
 import { useCallback } from 'react';
 
-import type { PayMethodType } from '@/defines';
-
 import type { Plan } from '../../useService';
 
 export interface UseActionReturn {
@@ -10,7 +8,7 @@ export interface UseActionReturn {
 
 export interface UseActionParams {
     selectedPlan: Plan | null;
-    selectedPayMethod: PayMethodType | null;
+    selectedPayMethod: string | null;
 }
 
 export function useAction({ selectedPlan, selectedPayMethod }: UseActionParams): UseActionReturn {

+ 9 - 13
src/pages/pricing/components/PayMethodCard/index.tsx

@@ -2,22 +2,18 @@ import { memo } from 'react';
 
 import { Icon } from '@iconify/react';
 
-import type { PayMethodType } from '@/defines';
 import { useResponsive } from '@/hooks/useSize';
 import checkOnIcon from '@/assets/iconify/multi-color/check-on.svg';
 import checkOffIcon from '@/assets/iconify/multi-color/check-off.svg';
 
-import { useService } from './useService';
-
-export interface PlanCardProps {
-    payMethodType: PayMethodType;
+export interface PayMethodCardProps {
+    item: API.PayTypeItem;
     isSelected?: boolean;
     onClick?: () => void;
 }
 
-const PlanCard = memo(({ payMethodType, isSelected = false, onClick }: PlanCardProps) => {
+const PayMethodCard = memo(({ item, isSelected = false, onClick }: PayMethodCardProps) => {
     const { isMobile } = useResponsive();
-    const { payMethodInfo } = useService(payMethodType);
 
     return (
         <div
@@ -33,21 +29,21 @@ const PlanCard = memo(({ payMethodType, isSelected = false, onClick }: PlanCardP
             onClick={onClick}
         >
             <div className="flex items-center gap-2">
-                <div className="w-[50px] h-8 rounded-[4px] border border-[#d9d9d9] bg-white flex items-center justify-center">
-                    <Icon icon={payMethodInfo.icon} className="h-5 w-auto" />
+                <div className="w-[50px] h-8 rounded-[4px] border border-[#d9d9d9] bg-white flex items-center justify-center overflow-hidden">
+                    <img src={item.icon} alt={item.name} className="h-5 w-auto max-w-[42px] object-contain" />
                 </div>
                 <span className="text-white text-2xl font-bold leading-8 whitespace-nowrap">
-                    {payMethodInfo.name}
+                    {item.name}
                 </span>
             </div>
             <Icon
                 icon={isSelected ? checkOnIcon : checkOffIcon}
-                className={`w-6 h-6 flex-shrink-0`}
+                className="w-6 h-6 flex-shrink-0"
             />
         </div>
     );
 });
 
-PlanCard.displayName = 'PlanCard';
+PayMethodCard.displayName = 'PayMethodCard';
 
-export default PlanCard;
+export default PayMethodCard;

+ 0 - 66
src/pages/pricing/components/PayMethodCard/useService.tsx

@@ -1,66 +0,0 @@
-import { useMemo } from 'react';
-
-import { useTranslation } from 'react-i18next';
-import type { IconifyIcon } from '@iconify/react';
-import logosApple from '@/assets/iconify/multi-color/applepay.svg';
-import logosGooglePay from '@/assets/iconify/multi-color/googlepay.svg';
-import logosPaypal from '@/assets/iconify/multi-color/paypal.svg';
-import siAlipay from '@/assets/iconify/multi-color/alipay.svg';
-import siWechat from '@/assets/iconify/multi-color/wechatpay.svg';
-
-import { PayMethodType } from '@/defines';
-
-export interface PayMethodInfo {
-    payMethodType: PayMethodType;
-    name: string;
-    icon: IconifyIcon;
-}
-
-export function useService(payMethodType: PayMethodType) {
-    const { t } = useTranslation();
-
-    const payMethodInfo = useMemo<PayMethodInfo>((): PayMethodInfo => {
-        switch (payMethodType) {
-            case PayMethodType.WECHAT:
-                return {
-                    payMethodType: PayMethodType.WECHAT,
-                    name: t('pages.pricing.payMethod.wechat'),
-                    icon: siWechat,
-                };
-            case PayMethodType.ALIPAY:
-                return {
-                    payMethodType: PayMethodType.ALIPAY,
-                    name: t('pages.pricing.payMethod.alipay'),
-                    icon: siAlipay,
-                };
-            case PayMethodType.PAYPAL:
-                return {
-                    payMethodType: PayMethodType.PAYPAL,
-                    name: t('pages.pricing.payMethod.paypal'),
-                    icon: logosPaypal,
-                };
-            case PayMethodType.APPLE_PAY:
-                return {
-                    payMethodType: PayMethodType.APPLE_PAY,
-                    name: t('pages.pricing.payMethod.applePay'),
-                    icon: logosApple,
-                };
-            case PayMethodType.GOOGLE_PAY:
-                return {
-                    payMethodType: PayMethodType.GOOGLE_PAY,
-                    name: t('pages.pricing.payMethod.googlePay'),
-                    icon: logosGooglePay,
-                };
-            default:
-                return {
-                    payMethodType: PayMethodType.WECHAT,
-                    name: t('pages.pricing.payMethod.wechat'),
-                    icon: siWechat,
-                };
-        }
-    }, [payMethodType, t]);
-
-    return {
-        payMethodInfo,
-    };
-}

+ 5 - 5
src/pages/pricing/index.tsx

@@ -80,12 +80,12 @@ const Pricing = memo(() => {
                                     : 'flex flex-wrap justify-start gap-x-8 gap-y-4 [&>*]:flex-[1_1_calc(50%-1rem)] [&>*]:max-w-[calc(50%-1rem)]'
                             }
                         >
-                            {payMethods.map((payMethod) => (
+                            {payMethods.map((item) => (
                                 <PayMethodCard
-                                    key={payMethod}
-                                    payMethodType={payMethod}
-                                    isSelected={selectedPayMethod === payMethod}
-                                    onClick={() => handlePayMethodClick(payMethod)}
+                                    key={item.payType}
+                                    item={item}
+                                    isSelected={selectedPayMethod === item.payType}
+                                    onClick={() => handlePayMethodClick(item.payType)}
                                 />
                             ))}
                         </div>

+ 5 - 7
src/pages/pricing/useAction.ts

@@ -1,24 +1,22 @@
 import { useState, useCallback } from 'react';
 
-import { PayMethodType } from '@/defines';
-
 export interface UseActionReturn {
     selectedPlanId: string | null;
     handlePlanClick: (planId: string) => void;
-    selectedPayMethod: PayMethodType | null;
-    handlePayMethodClick: (payMethodId: PayMethodType) => void;
+    selectedPayMethod: string | null;
+    handlePayMethodClick: (payType: string) => void;
 }
 
 export function useAction(): UseActionReturn {
     const [selectedPlanId, setSelectedPlanId] = useState<string | null>(null);
-    const [selectedPayMethod, setSelectedPayMethod] = useState<PayMethodType | null>(null);
+    const [selectedPayMethod, setSelectedPayMethod] = useState<string | null>(null);
 
     const handlePlanClick = useCallback((planId: string) => {
         setSelectedPlanId(planId);
     }, []);
 
-    const handlePayMethodClick = useCallback((payMethodId: PayMethodType) => {
-        setSelectedPayMethod(payMethodId);
+    const handlePayMethodClick = useCallback((payType: string) => {
+        setSelectedPayMethod(payType);
     }, []);
 
     return {

+ 14 - 14
src/pages/pricing/useService.ts

@@ -1,8 +1,8 @@
-import { useEffect, useMemo, useState } from 'react';
+import { useEffect, useState } from 'react';
 
-import { PlanTagType, PayMethodType } from '@/defines';
+import { PlanTagType } from '@/defines';
 import { userConfigModel } from '@/models/userConfigModel';
-import { fetchGetUserConfig, fetchPlanList } from '@/services/config';
+import { fetchGetUserConfig, fetchPlanList, fetchPayTypeList } from '@/services/config';
 import { setToken, userKey } from '@/utils/authUtils';
 import { secureLocalStorage as ls } from '@/utils/localUtils';
 import { getUniqueSign } from '@/utils/stringUtils';
@@ -20,13 +20,15 @@ export interface Plan {
 
 export interface UseServiceReturn {
     plans: Plan[];
-    payMethods: PayMethodType[];
+    payMethods: API.PayTypeItem[];
 }
 
 export function useService(): UseServiceReturn {
     const { setUserConfig } = userConfigModel.useModel();
 
     const [plans, setPlans] = useState<Plan[]>([]);
+    const [payMethods, setPayMethods] = useState<API.PayTypeItem[]>([]);
+
     useEffect(() => {
         const userinfo = ls.getLocal<API.UserInfo>(userKey);
         const expired = (userinfo?.accessExpires ?? 0) - currentUnixTimestamp() <= 0;
@@ -61,16 +63,14 @@ export function useService(): UseServiceReturn {
             .catch(() => {});
     }, []);
 
-    const payMethods = useMemo<PayMethodType[]>(
-        () => [
-            PayMethodType.APPLE_PAY,
-            PayMethodType.GOOGLE_PAY,
-            // PayMethodType.PAYPAL,
-            // PayMethodType.WECHAT,
-            // PayMethodType.ALIPAY,
-        ],
-        []
-    );
+    useEffect(() => {
+        fetchPayTypeList({})
+            .then((res) => {
+                const list = res?.data?.payTypeList ?? [];
+                setPayMethods(list);
+            })
+            .catch(() => {});
+    }, []);
 
     return {
         plans,