Browse Source

refactor : DioProvider

dev
徐振升 2 weeks ago
parent
commit
9cdfd8da42
  1. 2
      .vscode/settings.json
  2. 56
      lib/app/bindings/initial_binding.dart
  3. 53
      lib/data/models/auth_model.dart
  4. 12
      lib/data/models/login_model.dart
  5. 19
      lib/data/providers/auth_provider.dart
  6. 265
      lib/data/providers/dio_provider.dart
  7. 38
      lib/data/providers/user_provider.dart
  8. 138
      lib/data/repositories/auth_repository.dart
  9. 24
      lib/modules/auth/bindings/auth_binding.dart
  10. 139
      lib/modules/auth/controllers/auth_controller.dart
  11. 2
      lib/modules/auth/views/login_page.dart
  12. 22
      lib/modules/home/bindings/home_binding.dart
  13. 17
      lib/modules/my/bingdings/change_password_binding.dart
  14. 10
      lib/modules/my/controllers/change_password_controller.dart
  15. 27
      lib/modules/my/views/change_password.dart
  16. 3
      lib/modules/problem/bindings/problem_binding.dart
  17. 9
      lib/modules/problem/controllers/problem_controller.dart
  18. 2
      macos/Flutter/GeneratedPluginRegistrant.swift
  19. 64
      pubspec.lock
  20. 2
      pubspec.yaml

2
.vscode/settings.json vendored

@ -1,3 +1,3 @@
{
"cSpell.words": ["Getx", "tdesign"]
"cSpell.words": ["fenix", "Getx", "tdesign"]
}

56
lib/app/bindings/initial_binding.dart

@ -1,63 +1,15 @@
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart'; // debugPrint
import 'package:get_storage/get_storage.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/data/providers/dio_provider.dart';
import 'package:problem_check_system/data/providers/local_database.dart';
class InitialBinding implements Bindings {
@override
void dependencies() {
// GetStorage - 使 put
Get.put<GetStorage>(GetStorage(), permanent: true);
// Dio - 使 put lazyPut
Get.put<Dio>(createDioInstance());
//
Get.put<LocalDatabase>(LocalDatabase());
Get.put<ConnectivityProvider>(ConnectivityProvider());
}
// Dio
Dio createDioInstance() {
final dio = Dio(
BaseOptions(
baseUrl: 'https://xhdev.anxincloud.cn', //
connectTimeout: const Duration(seconds: 15),
receiveTimeout: const Duration(seconds: 15),
),
);
//
if (kDebugMode) {
dio.interceptors.add(
LogInterceptor(
requestBody: true,
responseBody: true,
logPrint: (o) => debugPrint(o.toString()),
),
);
}
//
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
final token = ""; //todo token
if (token != null && token.isNotEmpty) {
options.headers['Authorization'] = 'Bearer $token';
}
return handler.next(options);
},
onError: (DioException e, handler) {
if (e.response?.statusCode == 401) {
// 401 Unauthorized
Get.offAllNamed('/login');
}
return handler.next(e);
},
),
);
return dio;
Get.put<DioProvider>(DioProvider(), permanent: true);
Get.put<LocalDatabase>(LocalDatabase(), permanent: true);
Get.put<ConnectivityProvider>(ConnectivityProvider(), permanent: true);
}
}

53
lib/data/models/auth_model.dart

@ -0,0 +1,53 @@
///
class LoginRequest {
final String username;
final String password;
final String wechatJsCode;
LoginRequest({
required this.username,
required this.password,
this.wechatJsCode = "",
});
Map<String, dynamic> toJson() {
return {
'username': username,
'password': password,
'wechatJsCode': wechatJsCode,
};
}
// Map LoginRequest
factory LoginRequest.fromJson(Map<String, dynamic> json) {
return LoginRequest(
username: json['username'] as String,
password: json['password'] as String,
wechatJsCode: json['wechatJsCode'] as String,
);
}
}
///
class LoginResponse {
final String token;
final String refreshToken;
final int expires;
final String name;
LoginResponse({
required this.token,
required this.refreshToken,
required this.expires,
required this.name,
});
factory LoginResponse.fromJson(Map<String, dynamic> json) {
return LoginResponse(
token: json['token'] ?? '',
refreshToken: json['refresh_token'] ?? '',
expires: json['expires'] ?? '',
name: json['name'] ?? '',
);
}
}

12
lib/data/models/login_model.dart

@ -1,12 +0,0 @@
class LoginModel {
final String username;
final String password;
// 使 const
const LoginModel({required this.username, required this.password});
// toMap 便 JSON Map
Map<String, dynamic> toMap() {
return {'username': username, 'password': password};
}
}

19
lib/data/providers/auth_provider.dart

@ -1,19 +0,0 @@
import 'package:dio/dio.dart';
import 'package:problem_check_system/data/models/login_model.dart';
class AuthProvider {
final String _signInUrl = '/api/Accounts/SignIn';
final Dio _dio;
AuthProvider({required Dio dio}) : _dio = dio;
Future<Response> signIn(LoginModel loginModel) async {
try {
final response = await _dio.post(_signInUrl, data: loginModel.toMap());
return response;
} on DioException {
rethrow;
}
}
}

265
lib/data/providers/dio_provider.dart

@ -0,0 +1,265 @@
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart' hide Response;
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:problem_check_system/data/repositories/auth_repository.dart';
import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart';
// DioProvider GetxService
// Dio
class DioProvider extends GetxService {
static const String _baseUrl = 'https://xh.anxincloud.cn';
late final Dio _dio;
@override
Future<void> onInit() async {
super.onInit();
_initDio();
}
// Dio
void _initDio() {
_dio = Dio(
BaseOptions(
baseUrl: _baseUrl,
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
sendTimeout: const Duration(seconds: 30),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
),
);
//
// 1. (AuthInterceptor): token 401
// 2. (ErrorInterceptor):
// 3. (LoggerInterceptor): 便
_dio.interceptors.addAll(_getInterceptors());
}
List<Interceptor> _getInterceptors() {
return [
_getAuthInterceptor(),
_getErrorInterceptor(),
if (kDebugMode) _getLoggerInterceptor(),
];
}
/// token 401
Interceptor _getAuthInterceptor() {
return InterceptorsWrapper(
//
onRequest: (options, handler) async {
try {
// AuthRepository token
final authRepository = Get.find<AuthRepository>();
final token = authRepository.getToken();
if (token != null && token.isNotEmpty) {
options.headers['Authorization'] = 'Bearer $token';
}
} catch (e) {
// AuthRepository
debugPrint('AuthRepository 未找到。跳过认证头。');
}
return handler.next(options);
},
//
onError: (error, handler) async {
// 401 Unauthorized
if (error.response?.statusCode == 401) {
try {
final authRepository = Get.find<AuthRepository>();
// token
await authRepository.refreshToken();
//
final newOptions = Options(
method: error.requestOptions.method,
headers: error.requestOptions.headers
..['Authorization'] = 'Bearer ${authRepository.getToken()}',
);
final response = await _dio.request(
error.requestOptions.path,
data: error.requestOptions.data,
queryParameters: error.requestOptions.queryParameters,
options: newOptions,
);
// 使 handler.resolve()
return handler.resolve(response);
} on Exception catch (e) {
debugPrint('刷新 token 失败: $e');
// token
try {
final authController = Get.find<AuthController>();
await authController.logout();
} catch (e) {
// AuthController
final authRepository = Get.find<AuthRepository>();
authRepository.clearAuthData();
if (Get.currentRoute != '/login') {
Get.offAllNamed('/login');
}
}
//
return handler.next(error);
}
}
// 401
return handler.next(error);
},
);
}
///
Interceptor _getLoggerInterceptor() {
return PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseHeader: true,
responseBody: true,
error: true,
compact: false,
maxWidth: 90,
);
}
/// Snackbar
Interceptor _getErrorInterceptor() {
return InterceptorsWrapper(
onError: (error, handler) {
//
if (error.type == DioExceptionType.connectionTimeout ||
error.type == DioExceptionType.receiveTimeout ||
error.type == DioExceptionType.sendTimeout) {
Get.snackbar('网络超时', '请检查网络连接后重试');
} else if (error.type == DioExceptionType.unknown) {
Get.snackbar('网络异常', '请检查网络连接后重试');
}
// AuthInterceptor 401
if (error.response != null) {
final message = _handleStatusCode(error.response!);
Get.snackbar('请求错误', message);
}
return handler.next(error);
},
);
}
/// HTTP
String _handleStatusCode(Response response) {
switch (response.statusCode) {
case 400:
return response.data?['detail'] ?? '请求参数错误';
case 401:
return response.data?['detail'] ??
'未授权,请重新登录'; // 401
case 403:
return response.data?['detail'] ?? '访问被拒绝';
case 404:
return response.data?['detail'] ?? '请求资源不存在';
case 422:
final errors = response.data?['errors'];
if (errors != null && errors is Map && errors.isNotEmpty) {
return errors.values.first?.first?.toString() ?? '数据验证失败';
}
return response.data?['detail'] ?? '数据验证失败';
case 500:
return response.data?['detail'] ?? '服务器内部错误';
case 502:
return response.data?['detail'] ?? '网关错误';
case 503:
return response.data?['detail'] ?? '服务不可用';
default:
return response.data?['detail'] ?? '网络异常(${response.statusCode})';
}
}
void clear() {
_dio.interceptors.clear();
}
///
/// GET
Future<Response> get(
String path, {
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
}) async {
return await _dio.get(
path,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress,
);
}
/// POST
Future<Response> post(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
return await _dio.post(
path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
/// PUT
Future<Response> put(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
return await _dio.put(
path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
/// DELETE
Future<Response> delete(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
}) async {
return await _dio.delete(
path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
);
}
}

38
lib/data/providers/user_provider.dart

@ -1,38 +0,0 @@
import 'package:dio/dio.dart';
class UserProvider {
final Dio _dio;
// Dio
UserProvider({required Dio dio}) : _dio = dio;
/// API
///
/// @param newPassword
Future<Response> changePassword(String newPassword) async {
try {
final response = await _dio.post(
'/api/change_password', //
data: {
'new_password': newPassword,
},
);
return response;
} on DioException catch (e) {
// DioException 便
throw e;
}
}
/// API
///
///
Future<Response> getUserInfo() async {
try {
final response = await _dio.get('/api/user_info'); //
return response;
} on DioException catch (e) {
throw e;
}
}
}

138
lib/data/repositories/auth_repository.dart

@ -0,0 +1,138 @@
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:problem_check_system/data/models/auth_model.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/data/providers/dio_provider.dart';
class AuthRepository extends GetxService {
final DioProvider dioProvider;
final GetStorage storage;
final ConnectivityProvider connectivityProvider;
AuthRepository({
required this.dioProvider,
required this.storage,
required this.connectivityProvider,
});
static const String _tokenKey = 'token';
static const String _refreshTokenKey = 'refresh_token';
static const String _loginKey = 'user';
static const String _rememberPassword = 'remember_password';
void saveToken(String token) {
storage.write(_tokenKey, token);
}
String? getToken() {
return storage.read(_tokenKey);
}
void saveRefreshToken(String refreshToken) {
storage.write(_refreshTokenKey, refreshToken);
}
String? getRefreshToken() {
return storage.read(_refreshTokenKey);
}
void addLoginKey(LoginRequest login) {
storage.write(_loginKey, login.toJson());
}
///
LoginRequest getLoginKey() {
final loginData = storage.read(_loginKey);
//
if (loginData != null) {
//
return LoginRequest.fromJson(Map<String, dynamic>.from(loginData));
}
//
return LoginRequest(username: '', password: '');
}
void removeLoginKey() {
storage.remove(_loginKey);
}
void addRememberPassword(bool remembered) {
storage.write(_rememberPassword, remembered);
}
bool getRememberPassword() {
return storage.read(_rememberPassword);
}
void clearAuthData() {
storage.remove(_tokenKey);
storage.remove(_refreshTokenKey);
}
// 线
bool get isOnline {
return connectivityProvider.isOnline.value;
}
/// Check if a user is currently logged in by verifying the existence of a token.
bool isLoggedIn() {
final token = getToken();
return token != null && token.isNotEmpty;
}
/// Handles the user login process by calling the API and saving the response.
Future<LoginResponse> login(LoginRequest request) async {
try {
final response = await dioProvider.post(
'/api/Accounts/SignIn',
data: request.toJson(),
);
final loginResponse = LoginResponse.fromJson(response.data);
return loginResponse;
} catch (e) {
throw Exception(e);
}
}
/// Refreshes the authentication token using the refresh token.
Future<LoginResponse> refreshToken() async {
final refreshToken = getRefreshToken();
if (refreshToken == null || refreshToken.isEmpty) {
throw Exception('没有可用的刷新token');
}
try {
final response = await dioProvider.post(
'/auth/refresh',
data: {'refresh_token': refreshToken},
);
final authResponse = LoginResponse.fromJson(response.data);
saveToken(authResponse.token);
saveRefreshToken(authResponse.refreshToken);
return authResponse;
} catch (e) {
throw Exception(e);
}
}
/// Logs the user out by calling the API and then clearing local data.
Future<void> logout() async {
try {
// Attempt to call the API, but even if it fails, continue to clear local data.
await dioProvider.post('/auth/logout');
} on DioException catch (e) {
log('退出登录API调用失败: ${e.message}');
} finally {
// Regardless of API success or failure, always clear local storage.
clearAuthData();
}
}
}

24
lib/modules/auth/bindings/auth_binding.dart

@ -1,23 +1,33 @@
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import 'package:get_storage/get_storage.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/data/providers/dio_provider.dart';
import 'package:problem_check_system/data/repositories/auth_repository.dart';
import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart';
import 'package:problem_check_system/data/providers/auth_provider.dart';
class AuthBinding implements Bindings {
@override
void dependencies() {
// 1. (AuthProvider) Dio
// 使
Get.lazyPut<AuthProvider>(() => AuthProvider(dio: Get.find<Dio>()));
final DioProvider dioProvider = Get.find<DioProvider>();
final GetStorage storage = Get.find<GetStorage>();
final ConnectivityProvider connectivityProvider =
Get.find<ConnectivityProvider>();
Get.lazyPut<AuthRepository>(
() => AuthRepository(
dioProvider: dioProvider,
storage: storage,
connectivityProvider: connectivityProvider,
),
);
// 2. (AuthController) AuthProvider
// Get.find()
Get.lazyPut<AuthController>(
() => AuthController(
authProvider: Get.find<AuthProvider>(),
storage: Get.find<GetStorage>(),
),
() => AuthController(authRepository: Get.find<AuthRepository>()),
fenix: true,
);
}
}

139
lib/modules/auth/controllers/auth_controller.dart

@ -1,62 +1,45 @@
// lib/modules/auth/controllers/auth_controller.dart
import 'package:flutter/material.dart'; // 使 TextEditingController
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import 'package:get_storage/get_storage.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:problem_check_system/data/providers/auth_provider.dart';
import 'package:problem_check_system/data/models/login_model.dart';
import 'package:problem_check_system/data/models/auth_model.dart';
import 'package:problem_check_system/app/routes/app_routes.dart';
import 'package:problem_check_system/data/repositories/auth_repository.dart';
class AuthController extends GetxController {
final AuthProvider _authProvider;
final GetStorage _storage;
// TextEditingController
late final TextEditingController usernameController = TextEditingController();
late final TextEditingController passwordController = TextEditingController();
final AuthRepository _authRepository;
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final isLoading = false.obs;
final rememberPassword = false.obs;
static const _usernameKey = 'username';
static const _passwordKey = 'password';
AuthController({
required AuthProvider authProvider,
required GetStorage storage,
}) : _authProvider = authProvider,
_storage = storage;
AuthController({required AuthRepository authRepository})
: _authRepository = authRepository;
@override
void onInit() {
super.onInit();
_loadSavedCredentials();
_loadRememberedUser();
}
void _loadSavedCredentials() {
final savedUsername = _storage.read(_usernameKey);
final savedPassword = _storage.read(_passwordKey);
if (savedUsername != null && savedPassword != null) {
//
usernameController.text = savedUsername;
passwordController.text = savedPassword;
rememberPassword.value = true;
void _loadRememberedUser() {
final remember = _authRepository.getRememberPassword();
rememberPassword.value = remember;
if (remember) {
final loginData = _authRepository.getLoginKey();
usernameController.text = loginData.username;
passwordController.text = loginData.password;
}
}
String getToken() {
return _storage.read('token') ?? '';
/// Check if the user is already logged in by delegating to the repository.
bool isLoggedIn() {
return _authRepository.isLoggedIn();
}
// updateUsername updatePassword
// TextEditingController
///
Future<void> login() async {
//
final username = usernameController.text;
final password = passwordController.text;
final username = usernameController.text.trim();
final password = passwordController.text.trim();
if (username.isEmpty || password.isEmpty) {
Get.snackbar('输入错误', '用户名和密码不能为空');
@ -64,79 +47,53 @@ class AuthController extends GetxController {
}
isLoading.value = true;
final loginData = LoginRequest(username: username, password: password);
var connectivityResult = await (Connectivity().checkConnectivity());
bool isConnected =
connectivityResult.contains(ConnectivityResult.mobile) ||
connectivityResult.contains(ConnectivityResult.wifi) ||
connectivityResult.contains(ConnectivityResult.ethernet);
if (isConnected) {
await _onlineLogin(username, password);
if (_authRepository.isOnline) {
await _onlineLogin(loginData);
} else {
await _offlineLogin(username, password);
_offlineLogin(loginData);
}
isLoading.value = false;
}
Future<void> _onlineLogin(String username, String password) async {
/// 线
Future<void> _onlineLogin(LoginRequest loginRequest) async {
try {
final loginData = LoginModel(username: username, password: password);
final response = await _authProvider.signIn(loginData);
if (response.statusCode == 200 && response.data['token'] != null) {
final token = response.data['token'];
final refreshToken = response.data['refreshToken'];
_storage.write('token', token);
_storage.write('refreshToken', refreshToken);
//
if (rememberPassword.value) {
_storage.write(_usernameKey, username);
_storage.write(_passwordKey, password);
} else {
//
_storage.remove(_usernameKey);
_storage.remove(_passwordKey);
}
Get.offAllNamed(AppRoutes.home);
} else {
Get.snackbar('登录失败', '服务器返回了异常数据');
}
} on DioException catch (e) {
if (e.response?.data != null && e.response?.data['detail'] != null) {
final serverMessage = e.response!.data['detail'];
Get.snackbar('登录失败', serverMessage);
var loginResponse = await _authRepository.login(loginRequest);
//
_authRepository.saveToken(loginResponse.token);
_authRepository.saveRefreshToken(loginResponse.refreshToken);
_authRepository.addRememberPassword(rememberPassword.value);
if (rememberPassword.value) {
_authRepository.addLoginKey(loginRequest);
} else {
Get.snackbar('网络错误', '登录失败,请检查您的网络连接');
_authRepository.removeLoginKey();
}
Get.offAllNamed(AppRoutes.home);
} catch (e) {
Get.snackbar('错误', '发生未知错误: ${e.toString()}');
throw Exception(e);
}
}
Future<void> _offlineLogin(String username, String password) async {
final storedUsername = _storage.read(_usernameKey);
final storedPassword = _storage.read(_passwordKey);
void _offlineLogin(LoginRequest loginRequest) {
final loginData = _authRepository.getLoginKey();
if (storedUsername != null &&
storedPassword != null &&
storedUsername == username &&
storedPassword == password) {
if (loginData.username == loginRequest.username &&
loginData.password == loginRequest.password) {
Get.offAllNamed(AppRoutes.home);
Get.snackbar('离线登录成功', '您已离线登录到系统');
} else {
Get.snackbar('离线登录失败', '无网络连接,且无法验证本地凭证');
Get.snackbar('登录失败', '无网络连接,且无法验证本地凭证');
}
}
/// Handles the logout process by delegating to the repository.
Future<void> logout() async {
_storage.remove('token');
_storage.remove('refreshToken');
isLoading.value = true;
await _authRepository.logout();
isLoading.value = false;
Get.offAllNamed(AppRoutes.login);
}
}

2
lib/modules/auth/views/login_page.dart

@ -62,7 +62,7 @@ class LoginPage extends GetView<AuthController> {
width: 334.w,
height: 574.5.h,
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF).withOpacity(0.6),
color: const Color(0xFFFFFFFF).withValues(alpha: 153),
borderRadius: BorderRadius.all(Radius.circular(23.5.r)),
),
padding: EdgeInsets.all(24.w),

22
lib/modules/home/bindings/home_binding.dart

@ -1,9 +1,7 @@
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:problem_check_system/data/providers/auth_provider.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/data/providers/local_database.dart';
import 'package:problem_check_system/data/repositories/auth_repository.dart';
import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart';
import 'package:problem_check_system/modules/home/controllers/home_controller.dart';
import 'package:problem_check_system/modules/my/controllers/my_controller.dart';
@ -12,7 +10,6 @@ import 'package:problem_check_system/modules/problem/controllers/problem_control
class HomeBinding implements Bindings {
@override
void dependencies() {
final Dio dio = Get.find<Dio>();
final LocalDatabase database = Get.find<LocalDatabase>();
final ConnectivityProvider connectivityProvider =
Get.find<ConnectivityProvider>();
@ -21,18 +18,23 @@ class HomeBinding implements Bindings {
Get.lazyPut<ProblemController>(
() => ProblemController(
localDatabase: database,
dio: dio,
connectivityProvider: connectivityProvider,
dioProvider: Get.find(),
),
fenix: true,
);
Get.lazyPut<MyController>(() => MyController());
Get.lazyPut<AuthProvider>(() => AuthProvider(dio: dio));
Get.lazyPut<AuthController>(
() => AuthController(
authProvider: Get.find<AuthProvider>(),
storage: Get.find<GetStorage>(),
Get.lazyPut<AuthRepository>(
() => AuthRepository(
dioProvider: Get.find(),
storage: Get.find(),
connectivityProvider: connectivityProvider,
),
);
Get.lazyPut<AuthController>(
() => AuthController(authRepository: Get.find()),
fenix: true,
);
}
}

17
lib/modules/my/bingdings/change_password_binding.dart

@ -1,17 +1,20 @@
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:problem_check_system/data/repositories/auth_repository.dart';
import 'package:problem_check_system/modules/my/controllers/change_password_controller.dart';
import 'package:problem_check_system/data/providers/user_provider.dart'; // Provider
class ChangePasswordBinding implements Bindings {
@override
void dependencies() {
// ChangePasswordController UserProvider
final dio = Get.find<Dio>();
Get.lazyPut<UserProvider>(() => UserProvider(dio: dio));
Get.lazyPut<AuthRepository>(
() => AuthRepository(
dioProvider: Get.find(),
storage: Get.find(),
connectivityProvider: Get.find(),
),
);
Get.lazyPut<ChangePasswordController>(
//
() => ChangePasswordController(userProvider: Get.find()),
() => ChangePasswordController(authRepository: Get.find()),
);
}
}
}

10
lib/modules/my/controllers/change_password_controller.dart

@ -1,5 +1,5 @@
import 'package:get/get.dart';
import 'package:problem_check_system/data/providers/user_provider.dart'; // Provider
import 'package:problem_check_system/data/repositories/auth_repository.dart';
class ChangePasswordController extends GetxController {
//
@ -8,9 +8,9 @@ class ChangePasswordController extends GetxController {
var isLoading = false.obs;
// UserProvider API
final UserProvider _userProvider;
ChangePasswordController({required UserProvider userProvider})
: _userProvider = userProvider;
final AuthRepository _authRepository;
ChangePasswordController({required AuthRepository authRepository})
: _authRepository = authRepository;
//
void updateNewPassword(String value) {
@ -54,4 +54,4 @@ class ChangePasswordController extends GetxController {
isLoading.value = false;
}
}
}
}

27
lib/modules/my/views/change_password.dart

@ -9,7 +9,8 @@ class ChangePasswordPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
//
final ChangePasswordController controller = Get.find<ChangePasswordController>();
final ChangePasswordController controller =
Get.find<ChangePasswordController>();
return Scaffold(
appBar: _buildAppBar(),
@ -48,10 +49,7 @@ class ChangePasswordPage extends StatelessWidget {
centerTitle: true,
title: const Text(
'修改密码',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios, color: Colors.black),
@ -74,7 +72,7 @@ class ChangePasswordPage extends StatelessWidget {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
color: Colors.grey.withValues(alpha: 25.5),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
@ -98,10 +96,7 @@ class ChangePasswordPage extends StatelessWidget {
obscureText: obscureText,
decoration: InputDecoration(
hintText: hintText,
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 14.sp,
),
hintStyle: TextStyle(color: Colors.grey, fontSize: 14.sp),
border: InputBorder.none, // 线
isDense: true,
contentPadding: EdgeInsets.zero,
@ -129,10 +124,7 @@ class ChangePasswordPage extends StatelessWidget {
),
child: Text(
'取消',
style: TextStyle(
fontSize: 16.sp,
color: const Color(0xFF5695FD),
),
style: TextStyle(fontSize: 16.sp, color: const Color(0xFF5695FD)),
),
),
),
@ -153,14 +145,11 @@ class ChangePasswordPage extends StatelessWidget {
),
child: Text(
'确定',
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
),
style: TextStyle(fontSize: 16.sp, color: Colors.white),
),
),
),
],
);
}
}
}

3
lib/modules/problem/bindings/problem_binding.dart

@ -1,5 +1,4 @@
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import 'package:problem_check_system/data/providers/connectivity_provider.dart';
import 'package:problem_check_system/modules/problem/controllers/problem_controller.dart';
import 'package:problem_check_system/data/providers/local_database.dart';
@ -13,7 +12,7 @@ class ProblemBinding implements Bindings {
Get.lazyPut<ProblemController>(
() => ProblemController(
localDatabase: Get.find<LocalDatabase>(),
dio: Get.find<Dio>(),
dioProvider: Get.find(),
connectivityProvider: Get.find<ConnectivityProvider>(),
),
);

9
lib/modules/problem/controllers/problem_controller.dart

@ -5,6 +5,7 @@ import 'package:get/get.dart' hide MultipartFile, FormData;
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:problem_check_system/data/providers/dio_provider.dart';
import 'package:problem_check_system/modules/problem/views/widgets/custom_data_range_dropdown.dart';
import 'package:problem_check_system/data/models/problem_model.dart';
import 'package:problem_check_system/data/providers/local_database.dart';
@ -34,7 +35,7 @@ class ProblemController extends GetxController
///
final RxBool isLoading = false.obs;
final Dio _dio;
final DioProvider _dioProvider;
final ConnectivityProvider _connectivityProvider;
late TabController tabController;
@ -50,10 +51,10 @@ class ProblemController extends GetxController
ProblemController({
required LocalDatabase localDatabase,
required Dio dio,
required DioProvider dioProvider,
required ConnectivityProvider connectivityProvider,
}) : _localDatabase = localDatabase,
_dio = dio,
_dioProvider = dioProvider,
_connectivityProvider = connectivityProvider;
@override
@ -334,7 +335,7 @@ class ProblemController extends GetxController
}
}
final response = await _dio.post(
final response = await _dioProvider.post(
'https://your-server.com/api/problems',
data: formData,
options: Options(

2
macos/Flutter/GeneratedPluginRegistrant.swift

@ -8,13 +8,11 @@ import Foundation
import connectivity_plus
import file_selector_macos
import path_provider_foundation
import shared_preferences_foundation
import sqflite_darwin
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
}

64
pubspec.lock

@ -129,14 +129,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.1"
file_selector_linux:
dependency: transitive
description:
@ -552,62 +544,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.8"
shared_preferences:
pretty_dio_logger:
dependency: "direct main"
description:
name: shared_preferences
sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.5.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "5bcf0772a761b04f8c6bf814721713de6f3e5d9d89caf8d3fe031b02a342379e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.11"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.5.4"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
name: pretty_dio_logger
sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.3"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1"
version: "1.4.0"
sky_engine:
dependency: transitive
description: flutter

2
pubspec.yaml

@ -20,7 +20,7 @@ dependencies:
path: ^1.9.1
path_provider: ^2.1.5
permission_handler: ^12.0.1
shared_preferences: ^2.5.3
pretty_dio_logger: ^1.4.0
sqflite: ^2.4.2
tdesign_flutter: ^0.2.4
uuid: ^4.5.1

Loading…
Cancel
Save