重构 demo

This commit is contained in:
2026-02-05 00:09:57 +08:00
parent 2a6fd5149f
commit 01e597ac93
9 changed files with 981 additions and 638 deletions

129
hooks/useOTPBind.ts Normal file
View File

@@ -0,0 +1,129 @@
import { useState } from 'react';
import { WalletType } from 'rnwalletman';
export interface OTPBindCallbacks {
onRequestOTP: (walletType: WalletType, params: any) => Promise<any>;
onVerifyOTP: (walletType: WalletType, params: any) => Promise<any>;
onSuccess: (result: any) => void;
onError: (error: string) => void;
isDebug?: boolean;
}
export interface OTPBindState {
mobile: string;
otp: string;
step: 'mobile' | 'otp' | 'processing';
loading: boolean;
otpData: any;
}
export interface OTPBindActions {
setMobile: (mobile: string) => void;
setOtp: (otp: string) => void;
requestOTP: () => Promise<void>;
verifyOTP: () => Promise<void>;
resetToMobile: () => void;
}
export function useOTPBind(
walletType: WalletType,
callbacks: OTPBindCallbacks,
config?: {
otpLength?: number;
mobileLength?: number;
additionalParams?: any;
}
): [OTPBindState, OTPBindActions] {
const [mobile, setMobile] = useState('');
const [otp, setOtp] = useState('');
const [step, setStep] = useState<'mobile' | 'otp' | 'processing'>('mobile');
const [loading, setLoading] = useState(false);
const [otpData, setOtpData] = useState<any>(null);
const { onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug = false } = callbacks;
const { otpLength = 6, mobileLength = 10, additionalParams = {} } = config || {};
const log = (...args: any[]) => {
if (isDebug) console.log(`[${walletType}]`, ...args);
};
const error = (...args: any[]) => {
if (isDebug) console.error(`[${walletType}]`, ...args);
};
const requestOTP = async () => {
if (!mobile || mobile.length !== mobileLength) {
onError('Invalid mobile number');
return;
}
setLoading(true);
log('Requesting OTP for:', mobile);
try {
const response = await onRequestOTP(walletType, {
mobile,
...additionalParams,
});
log('OTP response:', response);
if (response.success) {
setOtpData(response.data);
setStep('otp');
} else {
error('OTP request failed:', response.message);
onError(response.message || 'Failed to request OTP');
}
} catch (e) {
error('Request OTP error:', e);
onError(e instanceof Error ? e.message : 'Failed to request OTP');
} finally {
setLoading(false);
}
};
const verifyOTP = async () => {
if (!otp || otp.length !== otpLength) {
onError(`Invalid OTP (expected ${otpLength} digits)`);
return;
}
setLoading(true);
setStep('processing');
log('Verifying OTP:', otp);
try {
const response = await onVerifyOTP(walletType, {
mobile,
otp,
...additionalParams,
...(otpData || {}),
});
log('Verify response:', response);
if (response.success) {
onSuccess(response.data);
} else {
error('Verify failed:', response.message);
setStep('otp');
onError(response.message || 'Failed to verify OTP');
}
} catch (e) {
error('Verify OTP error:', e);
setStep('otp');
onError(e instanceof Error ? e.message : 'Failed to verify OTP');
} finally {
setLoading(false);
}
};
const resetToMobile = () => {
setStep('mobile');
setOtp('');
};
return [
{ mobile, otp, step, loading, otpData },
{ setMobile, setOtp, requestOTP, verifyOTP, resetToMobile },
];
}