| New file |
| | |
| | | import Taro, { useDidShow } from '@tarojs/taro'; |
| | | import { View, Text, Image } from '@tarojs/components'; |
| | | import { useCallback, useEffect, useRef, useState } from 'react'; |
| | | import backIcon from '../../assets/mine-back.png'; |
| | | import arrowIcon from '../../assets/mine-arrow.png'; |
| | | import payMiniIcon from '../../assets/pay-mini-icon.png'; |
| | | import { getPayPwd, RobotaxiPaySettingStatus, setPayPwd } from '../../api/payment'; |
| | | |
| | | import './index.less'; |
| | | |
| | | /** 支付分小程序回跳 appId。 */ |
| | | const CREDIT_PAY_MINIPROGRAM_APP_ID = 'wxd8f3793ea3b935b8'; |
| | | |
| | | /** 页面显示状态文案。 */ |
| | | const PAY_SETTING_STATUS_TEXT = { |
| | | enabled: '已开通', |
| | | disabled: '未开通' |
| | | }; |
| | | |
| | | /** AppShow 监听函数类型。 */ |
| | | type AppShowHandler = (payload: any) => void; |
| | | |
| | | export default function PaymentSetting() { |
| | | const [isPayEnabled, setIsPayEnabled] = useState(false); // 当前是否已开通支付分 |
| | | const [isOperating, setIsOperating] = useState(false); // 当前是否正在执行操作 |
| | | const appShowListenerRef = useRef<AppShowHandler | null>(null); // 支付分回跳监听器 |
| | | const waitingCreditPayReturnRef = useRef(false); // 是否正在等待支付分签约页回跳 |
| | | |
| | | /** |
| | | * 清理支付分回跳监听。 |
| | | */ |
| | | const clearCreditPayReturnListener = useCallback(() => { |
| | | if (!appShowListenerRef.current) { |
| | | return; |
| | | } |
| | | Taro.offAppShow(appShowListenerRef.current); |
| | | appShowListenerRef.current = null; |
| | | }, []); |
| | | |
| | | /** |
| | | * 请求支付分开通状态。 |
| | | */ |
| | | const requestPayStatus = useCallback(async () => { |
| | | const response = await getPayPwd(); |
| | | return response === true; |
| | | }, []); |
| | | |
| | | /** |
| | | * 刷新支付分开通状态。 |
| | | */ |
| | | const refreshPayStatus = useCallback(async (showErrorToast = true) => { |
| | | try { |
| | | const nextStatus = await requestPayStatus(); |
| | | setIsPayEnabled(nextStatus); |
| | | return nextStatus; |
| | | } catch (error) { |
| | | if (showErrorToast) { |
| | | Taro.showToast({ title: '查询支付设置失败', icon: 'none' }); |
| | | } |
| | | throw error; |
| | | } |
| | | }, [requestPayStatus]); |
| | | |
| | | /** |
| | | * 返回上一页。 |
| | | */ |
| | | const handleBack = () => { |
| | | Taro.navigateBack({ |
| | | fail: () => { |
| | | Taro.reLaunch({ url: '/robotaxi/pages/personal-center/index' }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 处理支付分签约回跳。 |
| | | */ |
| | | const handleCreditPayReturn = useCallback(async (payload: any) => { |
| | | if (payload?.scene !== 1038 || payload?.referrerInfo?.appId !== CREDIT_PAY_MINIPROGRAM_APP_ID) { |
| | | return; |
| | | } |
| | | |
| | | waitingCreditPayReturnRef.current = false; |
| | | clearCreditPayReturnListener(); |
| | | |
| | | try { |
| | | const nextStatus = await refreshPayStatus(false); |
| | | Taro.showToast({ |
| | | title: nextStatus ? '开通成功' : '开通未完成', |
| | | icon: nextStatus ? 'success' : 'none' |
| | | }); |
| | | } catch (error) { |
| | | Taro.showToast({ title: '查询签约结果失败', icon: 'none' }); |
| | | } finally { |
| | | setIsOperating(false); |
| | | } |
| | | }, [clearCreditPayReturnListener, refreshPayStatus]); |
| | | |
| | | /** |
| | | * 绑定支付分签约回跳监听。 |
| | | */ |
| | | const bindCreditPayReturnListener = useCallback(() => { |
| | | clearCreditPayReturnListener(); |
| | | const handleAppShow: AppShowHandler = (payload) => { |
| | | handleCreditPayReturn(payload); |
| | | }; |
| | | appShowListenerRef.current = handleAppShow; |
| | | Taro.onAppShow(handleAppShow); |
| | | }, [clearCreditPayReturnListener, handleCreditPayReturn]); |
| | | |
| | | /** |
| | | * 拉起微信支付分签约页。 |
| | | */ |
| | | const openCreditPaySign = useCallback((signStr: string) => { |
| | | const weappGlobal = (globalThis as any).wx; |
| | | if (typeof weappGlobal?.openBusinessView !== 'function') { |
| | | Taro.showToast({ title: '请升级微信版本后重试', icon: 'none' }); |
| | | return false; |
| | | } |
| | | |
| | | waitingCreditPayReturnRef.current = true; |
| | | bindCreditPayReturnListener(); |
| | | weappGlobal.openBusinessView({ |
| | | businessType: 'wxpayScoreEnable', |
| | | extraData: { |
| | | apply_permissions_token: signStr, |
| | | }, |
| | | fail: () => { |
| | | waitingCreditPayReturnRef.current = false; |
| | | clearCreditPayReturnListener(); |
| | | setIsOperating(false); |
| | | Taro.showToast({ title: '拉起支付分签约失败', icon: 'none' }); |
| | | } |
| | | }); |
| | | return true; |
| | | }, [bindCreditPayReturnListener, clearCreditPayReturnListener]); |
| | | |
| | | /** |
| | | * 处理点击支付设置项。 |
| | | */ |
| | | const handlePaySettingClick = async () => { |
| | | if (isOperating) { |
| | | return; |
| | | } |
| | | |
| | | const nextOperateStatus = isPayEnabled |
| | | ? RobotaxiPaySettingStatus.Disable |
| | | : RobotaxiPaySettingStatus.Enable; |
| | | |
| | | setIsOperating(true); |
| | | try { |
| | | const response = await setPayPwd(nextOperateStatus); |
| | | |
| | | if (nextOperateStatus === RobotaxiPaySettingStatus.Disable) { |
| | | const nextStatus = await refreshPayStatus(false); |
| | | Taro.showToast({ |
| | | title: nextStatus ? '关闭未完成' : '已关闭', |
| | | icon: nextStatus ? 'none' : 'success' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const signStr = String(response?.signStr || ''); |
| | | if (!signStr) { |
| | | Taro.showToast({ title: '获取签约信息失败', icon: 'none' }); |
| | | return; |
| | | } |
| | | |
| | | const launched = openCreditPaySign(signStr); |
| | | if (!launched) { |
| | | return; |
| | | } |
| | | } catch (error) { |
| | | Taro.showToast({ |
| | | title: isPayEnabled ? '关闭失败' : '开通失败', |
| | | icon: 'none' |
| | | }); |
| | | } finally { |
| | | if (!waitingCreditPayReturnRef.current) { |
| | | setIsOperating(false); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | useDidShow(() => { |
| | | if (waitingCreditPayReturnRef.current) { |
| | | return; |
| | | } |
| | | refreshPayStatus(false).catch(() => { }); |
| | | }); |
| | | |
| | | useEffect(() => { |
| | | return () => { |
| | | waitingCreditPayReturnRef.current = false; |
| | | clearCreditPayReturnListener(); |
| | | }; |
| | | }, [clearCreditPayReturnListener]); |
| | | |
| | | return ( |
| | | <View className='payment-setting-content'> |
| | | <View |
| | | className='payment-setting-item' |
| | | hoverClass='payment-setting-item-hover' |
| | | onClick={handlePaySettingClick} |
| | | > |
| | | <View className='payment-setting-item-left'> |
| | | <Image className='payment-setting-item-icon' src={payMiniIcon} /> |
| | | <Text className='payment-setting-item-label'>微信支付分 | 先乘后付</Text> |
| | | </View> |
| | | <View className='payment-setting-item-right'> |
| | | <Text className={`payment-setting-item-status ${isPayEnabled ? 'payment-setting-item-status-signed' : ''}`}> |
| | | {isPayEnabled ? PAY_SETTING_STATUS_TEXT.enabled : PAY_SETTING_STATUS_TEXT.disabled} |
| | | </Text> |
| | | <Image className='payment-setting-item-arrow' src={arrowIcon} /> |
| | | </View> |
| | | </View> |
| | | </View> |
| | | ); |
| | | } |