fix
This commit is contained in:
@@ -87,10 +87,33 @@ export const OTPBindUI: React.FC<OTPBindUIProps> = ({
|
|||||||
|
|
||||||
{showOtp && (
|
{showOtp && (
|
||||||
<>
|
<>
|
||||||
<Text style={styles.hint}>验证码已发送至 {state.mobile}</Text>
|
<Text style={styles.hint}>
|
||||||
|
{state.needPassword
|
||||||
|
? `验证码已发送至 ${state.mobile},该账号需输入密码`
|
||||||
|
: `验证码已发送至 ${state.mobile}`}
|
||||||
|
</Text>
|
||||||
{!!state.errorMessage && (
|
{!!state.errorMessage && (
|
||||||
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
||||||
)}
|
)}
|
||||||
|
{state.needPassword && (
|
||||||
|
<>
|
||||||
|
<Text style={styles.label}>Amazon 密码</Text>
|
||||||
|
<TextInput
|
||||||
|
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||||
|
placeholder="请输入账号密码"
|
||||||
|
placeholderTextColor="#aaa"
|
||||||
|
secureTextEntry
|
||||||
|
autoCapitalize="none"
|
||||||
|
autoCorrect={false}
|
||||||
|
value={state.password}
|
||||||
|
onChangeText={t => {
|
||||||
|
actions.setPassword(t);
|
||||||
|
if (state.errorMessage) actions.clearError();
|
||||||
|
}}
|
||||||
|
editable={!isLoading}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Text style={styles.label}>验证码</Text>
|
<Text style={styles.label}>验证码</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||||
|
|||||||
20
docs/流程图.mmd
Normal file
20
docs/流程图.mmd
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
graph TD
|
||||||
|
A[开始: 订单状态未支付] --> B{最后一次查单结果<br/>是否成功?}
|
||||||
|
B -- 失败 --> C[标记: 接口异常/待重试]
|
||||||
|
B -- 成功 --> D{系统内是否有<br/>匹配记录?}
|
||||||
|
|
||||||
|
D -- 有记录 --> E[按正常流程处理]
|
||||||
|
D -- 无记录 --> F[查询当天整天流水]
|
||||||
|
|
||||||
|
F --> G{当天是否有<br/>其它成功流水?}
|
||||||
|
G -- 有流水 --> H[结论: 没付<br/>原因: 流水正常/该单未付]
|
||||||
|
G -- 无流水 --> I[查询前1-2天流水]
|
||||||
|
|
||||||
|
I --> J{前1-2天是否有<br/>成功流水?}
|
||||||
|
J -- 有流水 --> H
|
||||||
|
J -- 无流水 --> K[结论: 判定为异常或死卡<br/>原因: 持续无数据,需检查通道]
|
||||||
|
|
||||||
|
%% 样式定义
|
||||||
|
style H fill:#f96,stroke:#333,stroke-width:2px
|
||||||
|
style K fill:#ff9,stroke:#333,stroke-width:2px
|
||||||
|
style C fill:#ccc,stroke:#333
|
||||||
BIN
docs/流程图.png
Normal file
BIN
docs/流程图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
@@ -12,6 +12,8 @@ export interface OTPBindCallbacks {
|
|||||||
export interface OTPBindState {
|
export interface OTPBindState {
|
||||||
mobile: string;
|
mobile: string;
|
||||||
otp: string;
|
otp: string;
|
||||||
|
password: string;
|
||||||
|
needPassword: boolean;
|
||||||
step: 'mobile' | 'otp' | 'processing';
|
step: 'mobile' | 'otp' | 'processing';
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
otpData: any;
|
otpData: any;
|
||||||
@@ -21,6 +23,7 @@ export interface OTPBindState {
|
|||||||
export interface OTPBindActions {
|
export interface OTPBindActions {
|
||||||
setMobile: (mobile: string) => void;
|
setMobile: (mobile: string) => void;
|
||||||
setOtp: (otp: string) => void;
|
setOtp: (otp: string) => void;
|
||||||
|
setPassword: (password: string) => void;
|
||||||
requestOTP: () => Promise<void>;
|
requestOTP: () => Promise<void>;
|
||||||
verifyOTP: () => Promise<void>;
|
verifyOTP: () => Promise<void>;
|
||||||
resetToMobile: () => void;
|
resetToMobile: () => void;
|
||||||
@@ -39,6 +42,8 @@ export function useOTPBind(
|
|||||||
): [OTPBindState, OTPBindActions] {
|
): [OTPBindState, OTPBindActions] {
|
||||||
const [mobile, setMobile] = useState('');
|
const [mobile, setMobile] = useState('');
|
||||||
const [otp, setOtp] = useState('');
|
const [otp, setOtp] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
const [needPassword, setNeedPassword] = useState(false);
|
||||||
const [step, setStep] = useState<'mobile' | 'otp' | 'processing'>('mobile');
|
const [step, setStep] = useState<'mobile' | 'otp' | 'processing'>('mobile');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [otpData, setOtpData] = useState<any>(null);
|
const [otpData, setOtpData] = useState<any>(null);
|
||||||
@@ -82,6 +87,7 @@ export function useOTPBind(
|
|||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setOtpData(response.data);
|
setOtpData(response.data);
|
||||||
|
setNeedPassword(!!response.data?.needPassword);
|
||||||
setStep('otp');
|
setStep('otp');
|
||||||
setErrorMessage('');
|
setErrorMessage('');
|
||||||
} else {
|
} else {
|
||||||
@@ -107,6 +113,12 @@ export function useOTPBind(
|
|||||||
onError(msg);
|
onError(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (needPassword && !password.trim()) {
|
||||||
|
const msg = '请输入 Amazon 账号密码';
|
||||||
|
setErrorMessage(msg);
|
||||||
|
onError(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setErrorMessage('');
|
setErrorMessage('');
|
||||||
@@ -117,6 +129,7 @@ export function useOTPBind(
|
|||||||
const response = await onVerifyOTP(walletType, {
|
const response = await onVerifyOTP(walletType, {
|
||||||
mobile,
|
mobile,
|
||||||
otp,
|
otp,
|
||||||
|
password: needPassword ? password : undefined,
|
||||||
...additionalParams,
|
...additionalParams,
|
||||||
...(otpData || {}),
|
...(otpData || {}),
|
||||||
});
|
});
|
||||||
@@ -144,11 +157,13 @@ export function useOTPBind(
|
|||||||
const resetToMobile = () => {
|
const resetToMobile = () => {
|
||||||
setStep('mobile');
|
setStep('mobile');
|
||||||
setOtp('');
|
setOtp('');
|
||||||
|
setPassword('');
|
||||||
|
setNeedPassword(false);
|
||||||
setErrorMessage('');
|
setErrorMessage('');
|
||||||
};
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ mobile, otp, step, loading, otpData, errorMessage },
|
{ mobile, otp, password, needPassword, step, loading, otpData, errorMessage },
|
||||||
{ setMobile, setOtp, requestOTP, verifyOTP, resetToMobile, clearError },
|
{ setMobile, setOtp, setPassword, requestOTP, verifyOTP, resetToMobile, clearError },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -801,7 +801,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
||||||
}}
|
}}
|
||||||
onVerifyOTP={async (wt, p) => {
|
onVerifyOTP={async (wt, p) => {
|
||||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionId: p.sessionId }));
|
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, {
|
||||||
|
sessionId: p.sessionId,
|
||||||
|
...(p.password ? { password: p.password } : {}),
|
||||||
|
}));
|
||||||
}}
|
}}
|
||||||
onSuccess={this.onOtpBindSuccess('showAmazonPayPersonalBind', 'Amazon Pay bound successfully')}
|
onSuccess={this.onOtpBindSuccess('showAmazonPayPersonalBind', 'Amazon Pay bound successfully')}
|
||||||
onError={() => {}}
|
onError={() => {}}
|
||||||
@@ -1054,10 +1057,6 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
bounces={false}
|
bounces={false}
|
||||||
>
|
>
|
||||||
{groups.map(({ walletType, items }) => {
|
{groups.map(({ walletType, items }) => {
|
||||||
if (items.length === 1) {
|
|
||||||
return this.renderWalletItem(items[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const expanded = !!expandedBoundWalletGroups[walletType];
|
const expanded = !!expandedBoundWalletGroups[walletType];
|
||||||
const color = WALLET_TYPE_COLORS[walletType] ?? '#888';
|
const color = WALLET_TYPE_COLORS[walletType] ?? '#888';
|
||||||
|
|
||||||
@@ -1079,7 +1078,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
|||||||
</View>
|
</View>
|
||||||
<View style={{ flex: 1, marginLeft: 12 }}>
|
<View style={{ flex: 1, marginLeft: 12 }}>
|
||||||
<Text style={s.boundWalletGroupTitle}>{formatWalletTypeLabel(walletType)}</Text>
|
<Text style={s.boundWalletGroupTitle}>{formatWalletTypeLabel(walletType)}</Text>
|
||||||
<Text style={s.boundWalletGroupSub}>{items.length} accounts</Text>
|
<Text style={s.boundWalletGroupSub}>{items.length} account{items.length > 1 ? 's' : ''}</Text>
|
||||||
</View>
|
</View>
|
||||||
<Text style={s.walletGroupChevron}>{expanded ? '▼' : '▶'}</Text>
|
<Text style={s.walletGroupChevron}>{expanded ? '▼' : '▶'}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
openMobikwikPayToBank,
|
openMobikwikPayToBank,
|
||||||
openPhonePePayToBank,
|
openPhonePePayToBank,
|
||||||
openFreechargePayToBank,
|
openFreechargePayToBank,
|
||||||
|
openAmazonPayPayToBank,
|
||||||
} from 'rnwalletman';
|
} from 'rnwalletman';
|
||||||
|
|
||||||
export default function TestScreen() {
|
export default function TestScreen() {
|
||||||
@@ -51,6 +52,12 @@ export default function TestScreen() {
|
|||||||
.catch((err: unknown) => Alert.alert('Error', String(err)));
|
.catch((err: unknown) => Alert.alert('Error', String(err)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAmazonPayPayToBank = () => {
|
||||||
|
openAmazonPayPayToBank()
|
||||||
|
.then((result: boolean) => console.log('Amazon Pay To Bank', result ? 'Success' : 'Failed'))
|
||||||
|
.catch((err: unknown) => Alert.alert('Error', String(err)));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.sectionTitle}>Test Tools</Text>
|
<Text style={styles.sectionTitle}>Test Tools</Text>
|
||||||
@@ -67,6 +74,9 @@ export default function TestScreen() {
|
|||||||
<TouchableOpacity style={[styles.btn, { backgroundColor: '#5468db' }]} onPress={handleFreechargePayToBank}>
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#5468db' }]} onPress={handleFreechargePayToBank}>
|
||||||
<Text style={styles.btnText}>Freecharge Pay To Bank Test</Text>
|
<Text style={styles.btnText}>Freecharge Pay To Bank Test</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#ff9900' }]} onPress={handleAmazonPayPayToBank}>
|
||||||
|
<Text style={styles.btnText}>Amazon Pay To Bank Test</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
<TouchableOpacity style={[styles.btn, { backgroundColor: '#3498db' }]} onPress={handleEcho}>
|
||||||
<Text style={styles.btnText}>Echo Test</Text>
|
<Text style={styles.btnText}>Echo Test</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|||||||
Reference in New Issue
Block a user