fix fix fix

This commit is contained in:
2026-06-27 17:07:02 +08:00
parent 7cbf86c42c
commit 3dab895aed
5 changed files with 82 additions and 39 deletions
+51 -31
View File
@@ -98,10 +98,9 @@ function groupBoundWallets(wallets: WalletItem[]) {
}));
}
function parseWalletId(walletId: string): { walletType: string; phone: string } | null {
const i = walletId.lastIndexOf('_');
if (i <= 0) return null;
return { walletType: walletId.slice(0, i), phone: walletId.slice(i + 1) };
/** 生成新 cardId,格式 {userId}_{ns近似} */
function newCardId(userId: number | string): string {
return `${userId}_${Date.now()}${String(Math.floor(Math.random() * 1e6)).padStart(6, '0')}`;
}
function getBindKeyForWallet(item: WalletItem): string | null {
@@ -175,6 +174,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
private clientId: string = '';
private appStateSubscription?: any;
/** 重绑时保留原 cardId,透传给 register/verifyOTP;新绑时为 undefined */
private _pendingCardId?: string;
/** OTP 绑定流程中暂存 cardIdrequestOTP 时生成,verifyOTP 时复用 */
private _otpCardId = '';
constructor(props: any) {
super(props);
@@ -270,19 +273,18 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
handleNotificationTap = (payload: FcmNotificationTapPayload) => {
if (payload.cmd !== 'rebind_wallet') return;
const { walletId, walletType, phone } = payload.params;
const item = walletId
? this.state.wallets.find(w => w.id === walletId)
const { cardId, walletType, phone } = payload.params;
const item = cardId
? this.state.wallets.find(w => w.id === cardId)
: undefined;
if (item) {
this.handleRebind(item);
return;
}
const parsed = walletId ? parseWalletId(walletId) : null;
const wt = walletType || parsed?.walletType;
const mobile = phone || parsed?.phone;
const wt = walletType;
const mobile = phone;
if (wt) {
const key = getBindKeyForWallet({ id: walletId ?? '', walletType: wt, otpMode: false });
const key = getBindKeyForWallet({ id: cardId ?? '', walletType: wt, otpMode: false });
if (key) this.openWalletBind(key, mobile);
}
};
@@ -404,6 +406,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
Alert.alert('Rebind', 'Unsupported wallet type');
return;
}
this._pendingCardId = item.id; // 重绑保留原 cardId
this.openWalletBind(key, item.phone);
};
@@ -421,8 +424,12 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
this.setState({ [key]: false } as any);
};
// 重绑用原 cardId,新绑生成新 cardId
const cardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
this._pendingCardId = undefined;
try {
await Api.instance.register(walletType, result);
await Api.instance.register(walletType, result, cardId);
finishSuccess();
} catch (error: any) {
const errMsg = (error as Error).message || '';
@@ -453,7 +460,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
chVersion: data.chVersion,
appVersion: data.appVersion ?? data.version ?? result.appVersion,
tokenExpiresAt: data.tokenExpiresAt ?? data.expiresAt,
});
}, cardId);
finishSuccess();
return;
} catch (retryErr) {
@@ -559,10 +566,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
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 }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showPaytmPersonalBind', 'Paytm Personal OTP')}
onError={() => {}}
@@ -631,10 +639,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
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 }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showPhonePePersonalBind', 'PhonePe Personal OTP')}
onError={() => {}}
@@ -653,10 +662,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
onVerifyOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showPaytmBusinessBind', 'Paytm Business bound successfully')}
onError={() => {}}
@@ -675,10 +685,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
onVerifyOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showPhonePeBusinessBind', 'PhonePe Business bound successfully')}
onError={() => {}}
@@ -730,10 +741,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
onVerifyOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showBharatPeBusinessBind', 'BharatPe Business bound successfully')}
onError={() => {}}
@@ -812,14 +824,15 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
try {
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
const otpParams = await this.ensureMobikwikOtpParams();
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, otpParams));
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, otpParams, this._otpCardId));
} catch (e) {
return { success: false, message: (e as Error).message };
}
}}
onVerifyOTP={async (wt, p) =>
this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, p))
this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, p, this._otpCardId))
}
onSuccess={this.onOtpBindSuccess('showMobikwikPersonalBind', 'Mobikwik bound successfully')}
onError={() => {}}
@@ -854,10 +867,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile));
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
}}
onVerifyOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { otpId: p.otpId, deviceId: p.deviceId, csrfId: p.csrfId, appFc: p.appFc }));
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { otpId: p.otpId, deviceId: p.deviceId, csrfId: p.csrfId, appFc: p.appFc }, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showFreechargePersonalBind', 'Freecharge bound successfully')}
onError={() => {}}
@@ -876,16 +890,17 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
isDebug
initialMobile={bindPrefillMobile}
onRequestOTP={async (wt, p) => {
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {
...(p.sessionId ? { sessionId: p.sessionId } : {}),
...(p.password ? { password: p.password } : {}),
}));
}, this._otpCardId));
}}
onVerifyOTP={async (wt, p) => {
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, {
sessionId: p.sessionId,
...(p.password ? { password: p.password } : {}),
}));
}, this._otpCardId));
}}
onSuccess={this.onOtpBindSuccess('showAmazonPayPersonalBind', 'Amazon Pay bound successfully')}
onError={() => {}}
@@ -896,7 +911,9 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
return null;
};
openWalletBind = (key: string, prefillMobile?: string) => {
openWalletBind = (key: string, prefillMobile?: string, cardId?: string) => {
// 若从外部明确指定 cardId 则覆盖,否则保留之前 handleRebind 设的值
if (cardId !== undefined) this._pendingCardId = cardId;
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '' });
setTimeout(() => {
switch (key) {
@@ -1192,7 +1209,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
<WalletSelectModal
visible={this.state.showAddWallet}
onClose={() => this.setState({ showAddWallet: false })}
onSelectBind={this.openWalletBind}
onSelectBind={(key: string) => {
this._pendingCardId = undefined;
this.openWalletBind(key);
}}
/>
{this.renderVpaModal()}
</View>