修复token过期不跳转登录页:统一401和业务0002拦截,全局导航跳转
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import '../constants/api_endpoints.dart';
|
||||
import '../storage/local_storage.dart';
|
||||
import 'api_exception.dart';
|
||||
@@ -17,10 +18,13 @@ class NetworkConfig {
|
||||
class DioClient {
|
||||
late final Dio _dio;
|
||||
|
||||
/// 未授權回調(token 過期時觸發)
|
||||
VoidCallback? onUnauthorized;
|
||||
/// 全局導航 key,用於未授權時跳轉登錄頁
|
||||
GlobalKey<NavigatorState>? navigatorKey;
|
||||
|
||||
DioClient() {
|
||||
/// 未授權回調(token 過期時觸發 AuthProvider.forceLogout)
|
||||
VoidCallback? onForceLogout;
|
||||
|
||||
DioClient({this.navigatorKey}) {
|
||||
_dio = _createDio();
|
||||
_setupInterceptors();
|
||||
debugPrint('DioClient initialized with baseUrl: ${NetworkConfig.baseUrl}');
|
||||
@@ -97,12 +101,9 @@ class DioClient {
|
||||
if (data is Map<String, dynamic>) {
|
||||
final apiResponse = ApiResponse.fromJson(data, fromJson);
|
||||
// 檢測業務層未授權(後端返回 HTTP 200 + code "0002")
|
||||
// 注意:不再自動清除用戶數據,避免誤判
|
||||
// 只有在 HTTP 401 時才清除用戶數據
|
||||
if (apiResponse.isUnauthorized) {
|
||||
debugPrint('業務層未授權響應: ${apiResponse.message}');
|
||||
// 不再自動調用 onUnauthorized,避免刷新時誤判
|
||||
// onUnauthorized?.call();
|
||||
_handleUnauthorized();
|
||||
}
|
||||
return apiResponse;
|
||||
}
|
||||
@@ -120,8 +121,7 @@ class DioClient {
|
||||
debugPrint('====================');
|
||||
|
||||
if (_isUnauthorized(e)) {
|
||||
_clearUserData();
|
||||
onUnauthorized?.call();
|
||||
_handleUnauthorized();
|
||||
return ApiResponse.unauthorized('登錄已過期,請重新登錄');
|
||||
}
|
||||
|
||||
@@ -137,6 +137,19 @@ class DioClient {
|
||||
LocalStorage.clearUserData();
|
||||
}
|
||||
|
||||
/// 統一處理未授權:清除本地數據 → 通知 Provider → 全局跳轉登錄頁
|
||||
void _handleUnauthorized() {
|
||||
_clearUserData();
|
||||
onForceLogout?.call();
|
||||
final context = navigatorKey?.currentContext;
|
||||
if (context != null) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
'/login',
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _getErrorMessage(DioException e) {
|
||||
switch (e.type) {
|
||||
case DioExceptionType.connectionTimeout:
|
||||
|
||||
Reference in New Issue
Block a user