Files
flutter-template/lib/core/network/dio_client.dart
T
SkyJourney 61017f1c39 chore: 初始化脚手架 — sunny_mochi 企业级 Flutter 模板
Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库
7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系
5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter

通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
2026-05-14 12:51:05 +08:00

57 lines
2.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:dio/dio.dart';
import 'package:sunny_mochi/core/config/api_config.dart';
import 'package:sunny_mochi/core/config/env.dart';
import 'package:sunny_mochi/core/network/interceptors/auth_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/auth_logout_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/cert_pinning_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/error_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/log_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/retry_interceptor.dart';
import 'package:sunny_mochi/core/network/interceptors/token_refresh_interceptor.dart';
import 'package:sunny_mochi/core/network/mock/dio_mock_adapter.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'dio_client.g.dart';
/// 完整 7 拦截器栈:
/// CertPinning → Auth → TokenRefresh → Retry → Error → AuthLogout → Log
///
/// 顺序敏感:
/// - CertPinning 最早(在请求出去前校验)
/// - Auth 注 TokenTokenRefresh 在 401 时拦截再发
/// - Retry 在网络/5xx 错误时退避重试
/// - Error 把所有 DioException 映射为应用层 Failure
/// - **AuthLogout 必须在 Error 之后**:依赖 e.error 已被映射为 AuthFailure
/// - Log 最后,记录最终结果(Release 包 noop
@Riverpod(keepAlive: true)
Dio dioClient(Ref ref) {
final dio = Dio(
BaseOptions(
baseUrl: ApiConfig.baseUrl,
connectTimeout: ApiConfig.connectTimeout,
receiveTimeout: ApiConfig.receiveTimeout,
sendTimeout: ApiConfig.sendTimeout,
headers: const {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
),
);
dio.interceptors.addAll([
CertPinningInterceptor(),
AuthInterceptor(ref),
TokenRefreshInterceptor(ref, dio),
RetryInterceptor(dio),
ErrorInterceptor(),
AuthLogoutInterceptor(ref),
buildNetworkLogInterceptor(),
]);
if (Env.useMock) {
dio.httpClientAdapter = buildDefaultMockAdapter();
}
return dio;
}