Commit 95c34f90 by tanghuan

#1827 微信多开时,取消登陆,页面会一直显示等待中

1 parent f8c19f9e
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:appframe/config/constant.dart'; import 'package:appframe/config/constant.dart';
...@@ -69,13 +70,21 @@ class LoginMainState extends Equatable { ...@@ -69,13 +70,21 @@ class LoginMainState extends Equatable {
]; ];
} }
class LoginMainCubit extends Cubit<LoginMainState> { class LoginMainCubit extends Cubit<LoginMainState> with WidgetsBindingObserver {
late final Fluwx _fluwx; late final Fluwx _fluwx;
late final FluwxCancelable _fluwxCancelable; late final FluwxCancelable _fluwxCancelable;
late final WechatAuthRepository _wechatAuthRepository; late final WechatAuthRepository _wechatAuthRepository;
late final UserAuthRepository _userAuthRepository; late final UserAuthRepository _userAuthRepository;
// 是否正在等待微信授权回调;用于多微信选择器取消、用户中途返回等异常场景的兜底
bool _waitingWechatAuth = false;
// 总超时(请求已投递但长时间无任何回调时强制复位)
Timer? _wechatAuthTimeoutTimer;
// App 回到前台后的短延时(用于判定系统层取消)
Timer? _wechatAuthResumeTimer;
LoginMainCubit(super.initialState) { LoginMainCubit(super.initialState) {
WidgetsBinding.instance.addObserver(this);
_fluwx = getIt.get<Fluwx>(); _fluwx = getIt.get<Fluwx>();
// 处理微信安装检测 // 处理微信安装检测
...@@ -199,8 +208,9 @@ class LoginMainCubit extends Cubit<LoginMainState> { ...@@ -199,8 +208,9 @@ class LoginMainCubit extends Cubit<LoginMainState> {
return; return;
} }
// 控制显示加载框 // 控制显示加载框,并启动等待微信授权回调的兜底机制
emit(state.copyWith(loading: true)); emit(state.copyWith(loading: true));
_startWechatAuthWaiting();
} }
Future<void> wechatAuth() async { Future<void> wechatAuth() async {
...@@ -220,8 +230,9 @@ class LoginMainCubit extends Cubit<LoginMainState> { ...@@ -220,8 +230,9 @@ class LoginMainCubit extends Cubit<LoginMainState> {
return; return;
} }
// 控制显示加载框 // 控制显示加载框,并启动等待微信授权回调的兜底机制
emit(state.copyWith(loading: true)); emit(state.copyWith(loading: true));
_startWechatAuthWaiting();
} }
void goLoginPhone() { void goLoginPhone() {
...@@ -234,6 +245,8 @@ class LoginMainCubit extends Cubit<LoginMainState> { ...@@ -234,6 +245,8 @@ class LoginMainCubit extends Cubit<LoginMainState> {
void _responseListener(WeChatResponse response) async { void _responseListener(WeChatResponse response) async {
if (response is WeChatAuthResponse) { if (response is WeChatAuthResponse) {
// 收到正式回调,结束等待状态(不弹提示)
_finishWechatAuthWaiting();
if (response.code == null || response.code == '') { if (response.code == null || response.code == '') {
emit(state.copyWith(loading: false)); emit(state.copyWith(loading: false));
return; return;
...@@ -353,8 +366,78 @@ class LoginMainCubit extends Cubit<LoginMainState> { ...@@ -353,8 +366,78 @@ class LoginMainCubit extends Cubit<LoginMainState> {
} }
@override @override
void didChangeAppLifecycleState(AppLifecycleState appState) {
// App 回到前台时,如果仍在等待微信授权回调,给真实回调一个短窗口;
// 窗口内仍未收到 WeChatAuthResponse,则认定为系统层取消(典型场景:
// 设备装有多个微信,系统弹出选择器后用户点击取消,微信 SDK 根本不会回调)。
if (appState == AppLifecycleState.resumed && _waitingWechatAuth) {
_wechatAuthResumeTimer?.cancel();
_wechatAuthResumeTimer = Timer(const Duration(milliseconds: 1500), () {
if (_waitingWechatAuth) {
_finishWechatAuthWaiting(reason: _WechatAuthFinishReason.cancel);
}
});
}
}
// 标记进入"等待微信授权回调"状态,并启动总超时
void _startWechatAuthWaiting() {
_waitingWechatAuth = true;
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthTimeoutTimer = Timer(const Duration(seconds: 30), () {
if (_waitingWechatAuth) {
_finishWechatAuthWaiting(reason: _WechatAuthFinishReason.timeout);
}
});
}
// 结束等待,统一复位 loading 状态并按场景给出提示
void _finishWechatAuthWaiting({
_WechatAuthFinishReason reason = _WechatAuthFinishReason.response,
}) {
if (!_waitingWechatAuth) return;
_waitingWechatAuth = false;
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthResumeTimer?.cancel();
_wechatAuthTimeoutTimer = null;
_wechatAuthResumeTimer = null;
if (state.loading) {
emit(state.copyWith(loading: false));
}
switch (reason) {
case _WechatAuthFinishReason.cancel:
Fluttertoast.showToast(msg: '已取消微信授权', gravity: ToastGravity.TOP);
break;
case _WechatAuthFinishReason.timeout:
Fluttertoast.showToast(
msg: '微信授权超时,请重试',
gravity: ToastGravity.TOP,
backgroundColor: Colors.red,
);
break;
case _WechatAuthFinishReason.response:
// 正常收到回调时不弹提示
break;
}
}
@override
Future<void> close() { Future<void> close() {
WidgetsBinding.instance.removeObserver(this);
_wechatAuthTimeoutTimer?.cancel();
_wechatAuthResumeTimer?.cancel();
_fluwxCancelable.cancel(); _fluwxCancelable.cancel();
return super.close(); return super.close();
} }
}
enum _WechatAuthFinishReason {
// 收到了正式的 WeChatAuthResponse
response,
// App 已回到前台但仍无回调,判定为系统层/微信侧取消
cancel,
// 总超时
timeout,
} }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!