diff --git a/lib/app/bindings/initial_binding.dart b/lib/app/bindings/initial_binding.dart index 0dc0d74..620ccce 100644 --- a/lib/app/bindings/initial_binding.dart +++ b/lib/app/bindings/initial_binding.dart @@ -2,6 +2,7 @@ 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/local_database.dart'; class InitialBinding implements Bindings { @@ -9,11 +10,11 @@ class InitialBinding implements Bindings { void dependencies() { // 全局注册 GetStorage 实例 - 也改为使用 put 确保立即创建 Get.put(GetStorage(), permanent: true); - // 全局注册 Dio 实例 - 使用 put 而不是 lazyPut,并设置为永久 Get.put(createDioInstance()); // Get.put(LocalDatabase()); + Get.put(ConnectivityProvider()); } // 提取创建 Dio 实例的逻辑到单独的方法 diff --git a/lib/data/providers/connectivity_provider.dart b/lib/data/providers/connectivity_provider.dart new file mode 100644 index 0000000..5ea7d83 --- /dev/null +++ b/lib/data/providers/connectivity_provider.dart @@ -0,0 +1,62 @@ +// lib/data/providers/connectivity_provider.dart +import 'dart:async'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; + +class ConnectivityProvider extends GetxService { + final Connectivity _connectivity = Connectivity(); + final RxBool isOnline = false.obs; + late StreamSubscription> _connectivitySubscription; + + @override + void onInit() { + super.onInit(); + _initConnectivityListener(); + } + + @override + void onClose() { + _connectivitySubscription.cancel(); + super.onClose(); + } + + Future _initConnectivityListener() async { + _connectivitySubscription = _connectivity.onConnectivityChanged.listen(( + results, + ) { + final isConnected = results.any( + (result) => + result == ConnectivityResult.mobile || + result == ConnectivityResult.wifi || + result == ConnectivityResult.ethernet, + ); + isOnline.value = isConnected; + if (isConnected) { + Get.snackbar( + '网络状态', + '已连接到网络', + colorText: Colors.white, + backgroundColor: Colors.green, + snackPosition: SnackPosition.TOP, + ); + } else { + Get.snackbar( + '网络状态', + '已断开网络连接', + colorText: Colors.white, + backgroundColor: Colors.red, + snackPosition: SnackPosition.TOP, + ); + } + }); + + final initialResults = await _connectivity.checkConnectivity(); + isOnline.value = initialResults.any( + (result) => + result == ConnectivityResult.mobile || + result == ConnectivityResult.wifi || + result == ConnectivityResult.ethernet, + ); + } +} diff --git a/lib/modules/auth/bindings/auth_binding.dart b/lib/modules/auth/bindings/auth_binding.dart index 581a540..bc7b64e 100644 --- a/lib/modules/auth/bindings/auth_binding.dart +++ b/lib/modules/auth/bindings/auth_binding.dart @@ -1,5 +1,6 @@ import 'package:get/get.dart'; import 'package:dio/dio.dart'; +import 'package:get_storage/get_storage.dart'; import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart'; import 'package:problem_check_system/data/providers/auth_provider.dart'; @@ -13,7 +14,10 @@ class AuthBinding implements Bindings { // 2. 注入控制器 (AuthController),它依赖于 AuthProvider // 控制器通过 Get.find() 获取已注入的依赖 Get.lazyPut( - () => AuthController(authProvider: Get.find()), + () => AuthController( + authProvider: Get.find(), + storage: Get.find(), + ), ); } } diff --git a/lib/modules/auth/controllers/auth_controller.dart b/lib/modules/auth/controllers/auth_controller.dart index df3c25a..1b67bfd 100644 --- a/lib/modules/auth/controllers/auth_controller.dart +++ b/lib/modules/auth/controllers/auth_controller.dart @@ -1,68 +1,99 @@ +// lib/modules/auth/controllers/auth_controller.dart +import 'package:flutter/material.dart'; // 导入此库以使用 TextEditingController 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/app/routes/app_routes.dart'; class AuthController extends GetxController { final AuthProvider _authProvider; - AuthController({required AuthProvider authProvider}) - : _authProvider = authProvider; + final GetStorage _storage; + + // 将 TextEditingController 移动到控制器中,由控制器管理它们的生命周期 + late final TextEditingController usernameController; + late final TextEditingController passwordController; - final username = ''.obs; - final password = ''.obs; final isLoading = false.obs; final rememberPassword = false.obs; - final _box = GetStorage(); static const _usernameKey = 'username'; static const _passwordKey = 'password'; + AuthController({ + required AuthProvider authProvider, + required GetStorage storage, + }) : _authProvider = authProvider, + _storage = storage; + @override void onInit() { super.onInit(); + // 在 onInit 中初始化控制器 + usernameController = TextEditingController(); + passwordController = TextEditingController(); _loadSavedCredentials(); } + @override + void onClose() { + // 在 onClose 中销毁控制器,防止内存泄漏 + usernameController.dispose(); + passwordController.dispose(); + super.onClose(); + } + void _loadSavedCredentials() { - final savedUsername = _box.read(_usernameKey); - final savedPassword = _box.read(_passwordKey); + final savedUsername = _storage.read(_usernameKey); + final savedPassword = _storage.read(_passwordKey); if (savedUsername != null && savedPassword != null) { - username.value = savedUsername; - password.value = savedPassword; + // 从本地存储加载值,并设置给控制器 + usernameController.text = savedUsername; + passwordController.text = savedPassword; rememberPassword.value = true; } } String getToken() { - return ''; + return _storage.read('token') ?? ''; } - void updateUsername(String value) { - username.value = value; - } - - void updatePassword(String value) { - password.value = value; - } + // 移除了 updateUsername 和 updatePassword 方法,因为不再需要它们来同步值。 + // TextEditingController 本身就是值的来源。 Future login() async { - if (username.value.isEmpty || password.value.isEmpty) { + // 直接从控制器获取文本内容 + final username = usernameController.text; + final password = passwordController.text; + + if (username.isEmpty || password.isEmpty) { Get.snackbar('输入错误', '用户名和密码不能为空'); return; } isLoading.value = true; + 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); + } else { + await _offlineLogin(username, password); + } + + isLoading.value = false; + } + + Future _onlineLogin(String username, String password) async { try { - final loginData = LoginModel( - username: username.value, - password: password.value, - ); + final loginData = LoginModel(username: username, password: password); final response = await _authProvider.signIn(loginData); @@ -70,15 +101,17 @@ class AuthController extends GetxController { final token = response.data['token']; final refreshToken = response.data['refreshToken']; - _box.write('token', token); - _box.write('refreshToken', refreshToken); + _storage.write('token', token); + _storage.write('refreshToken', refreshToken); + // 如果记住密码,保存用户名和密码 if (rememberPassword.value) { - _box.write(_usernameKey, username.value); - _box.write(_passwordKey, password.value); + _storage.write(_usernameKey, username); + _storage.write(_passwordKey, password); } else { - _box.remove(_usernameKey); - _box.remove(_passwordKey); + // 否则清除所有本地凭据 + _storage.remove(_usernameKey); + _storage.remove(_passwordKey); } Get.offAllNamed(AppRoutes.home); @@ -94,18 +127,27 @@ class AuthController extends GetxController { } } catch (e) { Get.snackbar('错误', '发生未知错误: ${e.toString()}'); - } finally { - isLoading.value = false; } } - Future logout() async { - _box.remove('token'); - _box.remove('refreshToken'); - if (rememberPassword.value == false) { - _box.remove(_usernameKey); - _box.remove(_passwordKey); + Future _offlineLogin(String username, String password) async { + final storedUsername = _storage.read(_usernameKey); + final storedPassword = _storage.read(_passwordKey); + + if (storedUsername != null && + storedPassword != null && + storedUsername == username && + storedPassword == password) { + Get.offAllNamed(AppRoutes.home); + Get.snackbar('离线登录成功', '您已离线登录到系统'); + } else { + Get.snackbar('离线登录失败', '无网络连接,且无法验证本地凭证'); } + } + + Future logout() async { + _storage.remove('token'); + _storage.remove('refreshToken'); Get.offAllNamed(AppRoutes.login); } } diff --git a/lib/modules/auth/views/login_page.dart b/lib/modules/auth/views/login_page.dart index d6ea5ca..463b63b 100644 --- a/lib/modules/auth/views/login_page.dart +++ b/lib/modules/auth/views/login_page.dart @@ -1,43 +1,20 @@ +// lib/modules/auth/views/login_page.dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:problem_check_system/modules/auth/controllers/auth_controller.dart'; -class LoginPage extends StatelessWidget { +class LoginPage extends GetView { const LoginPage({super.key}); @override Widget build(BuildContext context) { - final AuthController controller = Get.find(); - - // 在 build 方法中创建并初始化 TextEditingController - final TextEditingController usernameController = TextEditingController( - text: controller.username.value, - ); - final TextEditingController passwordController = TextEditingController( - text: controller.password.value, - ); - - // 监听 AuthController 的响应式变量,以防它们在其他地方被修改 - // 并更新到 TextEditingController。 - // 这里使用 once() 或 ever() 都可以,但为了代码简洁, - // 我们主要关注初始同步。用户输入后,值会通过 onChanged 更新。 - usernameController.text = controller.username.value; - passwordController.text = controller.password.value; - return Scaffold( - resizeToAvoidBottomInset: false, - body: Stack( - children: [ - _buildBackground(), - _buildLoginCard(controller, usernameController, passwordController), - ], - ), + body: Stack(children: [_buildBackground(), _buildLoginCard(controller)]), ); } Widget _buildBackground() { - // ... 此部分代码不变 ... return Stack( children: [ Container( @@ -72,12 +49,8 @@ class LoginPage extends StatelessWidget { ); } - // 修改 _buildLoginCard 方法签名,传入控制器 - Widget _buildLoginCard( - AuthController controller, - TextEditingController usernameController, - TextEditingController passwordController, - ) { + // 修改 _buildLoginCard 方法,它不再需要传入 TextEditingController + Widget _buildLoginCard(AuthController controller) { return Positioned( left: 20.5.w, top: 220.5.h, @@ -85,7 +58,7 @@ class LoginPage extends StatelessWidget { width: 334.w, height: 574.5.h, decoration: BoxDecoration( - color: const Color(0xFFFFFFFF).withOpacity(0.6), // 使用 withOpacity 更清晰 + color: const Color(0xFFFFFFFF).withOpacity(0.6), borderRadius: BorderRadius.all(Radius.circular(23.5.r)), ), padding: EdgeInsets.all(24.w), @@ -93,20 +66,18 @@ class LoginPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), - // 使用新版 _buildTextFieldSection + // 直接使用控制器中的 TextEditingController _buildTextFieldSection( label: '账号', hintText: '请输入您的账号', - controller: usernameController, - onChanged: controller.updateUsername, // onChanged 保留,用于实时同步 + controller: controller.usernameController, ), const SizedBox(height: 22), _buildTextFieldSection( label: '密码', hintText: '请输入您的密码', obscureText: true, - controller: passwordController, - onChanged: controller.updatePassword, + controller: controller.passwordController, ), const SizedBox(height: 9.5), _buildRememberPasswordRow(controller), @@ -118,13 +89,12 @@ class LoginPage extends StatelessWidget { ); } - // 修改 _buildTextFieldSection 以接受 TextEditingController + // 修改 _buildTextFieldSection,不再需要 onChanged 回调 Widget _buildTextFieldSection({ required String label, required String hintText, required TextEditingController controller, bool obscureText = false, - required Function(String) onChanged, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -136,7 +106,6 @@ class LoginPage extends StatelessWidget { const SizedBox(height: 10.5), TextField( controller: controller, // 使用传入的控制器 - onChanged: onChanged, obscureText: obscureText, style: const TextStyle(color: Colors.black), decoration: InputDecoration( @@ -150,7 +119,6 @@ class LoginPage extends StatelessWidget { } Widget _buildRememberPasswordRow(AuthController controller) { - // ... 此部分代码不变 ... return Row( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -169,7 +137,6 @@ class LoginPage extends StatelessWidget { } Widget _buildLoginButton(AuthController controller) { - // ... 此部分代码不变 ... return SizedBox( width: double.infinity, child: ElevatedButton( diff --git a/lib/modules/home/bindings/home_binding.dart b/lib/modules/home/bindings/home_binding.dart index 80ded33..0798137 100644 --- a/lib/modules/home/bindings/home_binding.dart +++ b/lib/modules/home/bindings/home_binding.dart @@ -1,6 +1,8 @@ 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/modules/auth/controllers/auth_controller.dart'; import 'package:problem_check_system/modules/home/controllers/home_controller.dart'; @@ -12,15 +14,24 @@ class HomeBinding implements Bindings { void dependencies() { final Dio dio = Get.find(); final LocalDatabase database = Get.find(); + final ConnectivityProvider connectivityProvider = + Get.find(); // 惰性注入 HomeController,只在第一次被调用时创建 Get.lazyPut(() => HomeController()); Get.lazyPut( - () => ProblemController(localDatabase: database, dio: dio), + () => ProblemController( + localDatabase: database, + dio: dio, + connectivityProvider: connectivityProvider, + ), ); Get.lazyPut(() => MyController()); Get.lazyPut(() => AuthProvider(dio: dio)); Get.lazyPut( - () => AuthController(authProvider: Get.find()), + () => AuthController( + authProvider: Get.find(), + storage: Get.find(), + ), ); } } diff --git a/lib/modules/my/views/my_page.dart b/lib/modules/my/views/my_page.dart index 202c272..7521d0f 100644 --- a/lib/modules/my/views/my_page.dart +++ b/lib/modules/my/views/my_page.dart @@ -40,10 +40,7 @@ class MyPage extends StatelessWidget { gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, - colors: [ - const Color(0xFFE4F0FF), - const Color(0xFFF1F7FF).withValues(alpha: 25.5), - ], + colors: [const Color(0xFF418CFC), const Color(0x713DBFFC)], ), ), ), diff --git a/lib/modules/problem/bindings/problem_binding.dart b/lib/modules/problem/bindings/problem_binding.dart index 5840803..4fc8e2e 100644 --- a/lib/modules/problem/bindings/problem_binding.dart +++ b/lib/modules/problem/bindings/problem_binding.dart @@ -1,5 +1,6 @@ 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,6 +14,7 @@ class ProblemBinding implements Bindings { () => ProblemController( localDatabase: Get.find(), dio: Get.find(), + connectivityProvider: Get.find(), ), ); } diff --git a/lib/modules/problem/controllers/problem_controller.dart b/lib/modules/problem/controllers/problem_controller.dart index a645e20..7a39792 100644 --- a/lib/modules/problem/controllers/problem_controller.dart +++ b/lib/modules/problem/controllers/problem_controller.dart @@ -1,27 +1,34 @@ +// modules/problem/controllers/problem_controller.dart import 'package:dio/dio.dart'; import 'package:get/get.dart' hide MultipartFile, FormData; import 'dart:io'; import 'package:path/path.dart' as path; import '../../../data/models/problem_model.dart'; import '../../../data/providers/local_database.dart'; +import '../../../data/providers/connectivity_provider.dart'; // 更新路径 class ProblemController extends GetxController { final LocalDatabase _localDatabase; final RxList problems = [].obs; final RxBool isLoading = false.obs; final Dio _dio; + final ConnectivityProvider _connectivityProvider; - // 依赖注入,由 bindings 传入所有依赖 - ProblemController({required LocalDatabase localDatabase, required Dio dio}) - : _localDatabase = localDatabase, - _dio = dio; + ProblemController({ + required LocalDatabase localDatabase, + required Dio dio, + required ConnectivityProvider connectivityProvider, + }) : _localDatabase = localDatabase, + _dio = dio, + _connectivityProvider = connectivityProvider; + + // 使用 provider 中的 isOnline + RxBool get isOnline => _connectivityProvider.isOnline; - // 获取所有已选中的问题对象 List get selectedProblems { return problems.where((p) => p.isChecked.value).toList(); } - // 获取未上传的问题 List get unuploadedProblems { return problems.where((p) => !p.isUploaded).toList(); } @@ -44,16 +51,13 @@ class ProblemController extends GetxController { } } - /// 在本地数据库和GetX列表中添加一个新问题 Future addProblem(Problem problem) async { try { - // 确保问题有ID if (problem.id == null) { problem = problem.copyWith( id: DateTime.now().millisecondsSinceEpoch.toString(), ); } - await _localDatabase.insertProblem(problem); problems.add(problem); } catch (e) { @@ -62,7 +66,6 @@ class ProblemController extends GetxController { } } - /// 在本地数据库和GetX列表中更新一个现有问题 Future updateProblem(Problem problem) async { try { await _localDatabase.updateProblem(problem); @@ -76,16 +79,11 @@ class ProblemController extends GetxController { } } - /// 删除单个问题 Future deleteProblem(Problem problem) async { try { if (problem.id != null) { await _localDatabase.deleteProblem(problem.id!); - - // 从本地列表中移除 problems.remove(problem); - - // 删除关联的图片文件 await _deleteProblemImages(problem); } } catch (e) { @@ -94,14 +92,12 @@ class ProblemController extends GetxController { } } - /// 批量删除选中的问题 Future deleteSelectedProblems() async { final problemsToDelete = selectedProblems; if (problemsToDelete.isEmpty) { Get.snackbar('提示', '请至少选择一个问题进行删除'); return; } - try { for (var problem in problemsToDelete) { await deleteProblem(problem); @@ -112,7 +108,6 @@ class ProblemController extends GetxController { } } - /// 删除问题关联的图片文件 Future _deleteProblemImages(Problem problem) async { for (var imagePath in problem.imagePaths) { try { @@ -126,7 +121,6 @@ class ProblemController extends GetxController { } } - /// 上传单个问题到服务器 Future uploadProblem(Problem problem) async { try { final formData = FormData.fromMap({ @@ -136,7 +130,6 @@ class ProblemController extends GetxController { 'boundInfo': problem.boundInfo ?? '', }); - // 添加图片文件 for (var imagePath in problem.imagePaths) { final file = File(imagePath); if (await file.exists()) { @@ -162,7 +155,6 @@ class ProblemController extends GetxController { ); if (response.statusCode == 200) { - // 标记为已上传 final updatedProblem = problem.copyWith(isUploaded: true); await updateProblem(updatedProblem); return true; @@ -183,8 +175,12 @@ class ProblemController extends GetxController { } } - /// 批量上传所有未上传的问题 Future uploadAllUnuploaded() async { + if (!isOnline.value) { + Get.snackbar('提示', '当前无网络,无法上传'); + return; + } + final unuploaded = unuploadedProblems; if (unuploaded.isEmpty) { Get.snackbar('提示', '没有需要上传的问题'); @@ -199,7 +195,6 @@ class ProblemController extends GetxController { if (success) { successCount++; } - // 添加短暂延迟,避免服务器压力过大 await Future.delayed(const Duration(milliseconds: 500)); } @@ -214,7 +209,6 @@ class ProblemController extends GetxController { } } - /// 绑定信息到问题 Future bindInfoToProblem(String id, String info) async { try { final problem = problems.firstWhere((p) => p.id == id); @@ -226,7 +220,6 @@ class ProblemController extends GetxController { } } - /// 清除所有选中的状态 void clearSelections() { for (var problem in problems) { problem.isChecked.value = false; diff --git a/lib/modules/problem/views/problem_page.dart b/lib/modules/problem/views/problem_page.dart index 0b03d58..7ef64d3 100644 --- a/lib/modules/problem/views/problem_page.dart +++ b/lib/modules/problem/views/problem_page.dart @@ -1,3 +1,4 @@ +// problem_page.dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -28,12 +29,9 @@ class ProblemPage extends StatelessWidget { alignment: Alignment.bottomLeft, decoration: const BoxDecoration( gradient: LinearGradient( - begin: Alignment.centerLeft, // 从左开始 - end: Alignment.centerRight, // 到右结束 - colors: [ - Color(0xFF418CFC), // 左侧颜色 - Color(0xFF3DBFFC), // 右侧颜色 - ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], ), ), child: TabBar( @@ -50,17 +48,17 @@ class ProblemPage extends StatelessWidget { Tab(text: '历史问题列表'), ], labelStyle: TextStyle( - fontFamily: 'MyFont', // 字体名称 - fontWeight: FontWeight.w800, // 字重 - fontSize: 14.sp, // 字体大小 + fontFamily: 'MyFont', + fontWeight: FontWeight.w800, + fontSize: 14.sp, ), unselectedLabelStyle: TextStyle( fontFamily: 'MyFont', fontWeight: FontWeight.w800, fontSize: 14.sp, ), - labelColor: Colors.black, // 选中文字颜色 - unselectedLabelColor: Colors.white, // 未选中文字颜色 + labelColor: Colors.black, + unselectedLabelColor: Colors.white, ), ), Expanded( @@ -139,30 +137,32 @@ class ProblemPage extends StatelessWidget { ], ), ), - floatingActionButton: FloatingActionButton( - heroTag: "abc", - onPressed: () { - // 批量上传功能 - problemController.uploadAllUnuploaded(); - }, - foregroundColor: Colors.white, - backgroundColor: Colors.red[300], - child: const Icon(Icons.file_upload_outlined), - ), + floatingActionButton: Obx(() { + final bool isOnline = problemController.isOnline.value; + return FloatingActionButton( + heroTag: "abc", + onPressed: isOnline + ? () => problemController.uploadAllUnuploaded() + : null, + foregroundColor: Colors.white, + backgroundColor: isOnline ? Colors.red[300] : Colors.grey[400], + child: Icon( + isOnline ? Icons.file_upload_outlined : Icons.cloud_off_outlined, + ), + ); + }), ), ); } - // 构建可滑动的ProblemCard组件 Widget _buildSwipeableProblemCard( Problem problem, ProblemController controller, { ProblemCardViewType viewType = ProblemCardViewType.buttons, }) { - // 使用Dismissible组件实现左滑删除 return Dismissible( key: Key(problem.id ?? UniqueKey().toString()), - direction: DismissDirection.endToStart, // 只允许从右向左滑动 + direction: DismissDirection.endToStart, background: Container( color: Colors.red, alignment: Alignment.centerRight, @@ -170,11 +170,9 @@ class ProblemPage extends StatelessWidget { child: Icon(Icons.delete, color: Colors.white, size: 30.sp), ), confirmDismiss: (direction) async { - // 显示确认对话框 return await _showDeleteConfirmationDialog(problem); }, onDismissed: (direction) { - // 用户确认后执行删除操作 controller.deleteProblem(problem); Get.snackbar('成功', '问题已删除'); }, @@ -182,9 +180,7 @@ class ProblemPage extends StatelessWidget { ); } - // 显示删除确认对话框 Future _showDeleteConfirmationDialog(Problem problem) async { - // 使用 Get.bottomSheet 实现底部确认表单 return await Get.bottomSheet( Container( padding: EdgeInsets.symmetric(horizontal: 16.0), @@ -200,7 +196,6 @@ class ProblemPage extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // 标题 SizedBox(height: 16), Text( '确认删除', @@ -208,14 +203,12 @@ class ProblemPage extends StatelessWidget { style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), SizedBox(height: 8), - // 内容 Text( '确定要删除这个问题吗?此操作不可撤销。', textAlign: TextAlign.center, style: TextStyle(fontSize: 14, color: Colors.grey[600]), ), SizedBox(height: 24), - // 删除按钮 ElevatedButton( onPressed: () => Get.back(result: true), style: ElevatedButton.styleFrom( @@ -231,7 +224,6 @@ class ProblemPage extends StatelessWidget { ), ), SizedBox(height: 8), - // 取消按钮 TextButton( onPressed: () => Get.back(result: false), style: TextButton.styleFrom( @@ -247,7 +239,7 @@ class ProblemPage extends StatelessWidget { ), ), ), - isDismissible: false, // 阻止用户点击外部关闭 + isDismissible: false, ) ?? false; } diff --git a/pubspec.lock b/pubspec.lock index 80703a6..a96742b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -74,7 +74,7 @@ packages: source: hosted version: "0.3.4+2" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" diff --git a/pubspec.yaml b/pubspec.yaml index f285d04..b290be6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: connectivity_plus: ^6.1.5 + crypto: ^3.0.6 dio: ^5.9.0 flutter: sdk: flutter