Browse Source

fix(login): 修复登录视图点击空白处键盘不收起的问题

refactor(login): 优化登录请求处理逻辑,增加超时和错误处理
- 为登录请求添加30秒超时控制
- 完善错误处理,增加用户友好的错误提示
- 添加finally块确保加载状态重置

refactor(version): 简化版本更新服务逻辑,默认使用官方下载
newdev_shunjiawei
lxm 1 year ago
parent
commit
a00afe6295
  1. 42
      lib/data/services/version_update_service.dart
  2. 119
      lib/modules/login/controllers/login_controller.dart
  3. 17
      lib/modules/login/views/login_view.dart

42
lib/data/services/version_update_service.dart

@ -270,29 +270,29 @@ class VersionUpdateService extends GetxService {
return false; return false;
} }
final platformInfo = await getCurrentPlatformInfo(); //final platformInfo = await getCurrentPlatformInfo();
try { try {
switch (platformInfo.storeType) { // switch (platformInfo.storeType) {
case AppStoreType.appStore: // case AppStoreType.appStore:
return await _openAppStore(); // return await _openAppStore();
case AppStoreType.googlePlay: // case AppStoreType.googlePlay:
return await _openGooglePlay(); // return await _openGooglePlay();
case AppStoreType.huawei: // case AppStoreType.huawei:
return await _openHuaweiStore(); // return await _openHuaweiStore();
case AppStoreType.xiaomi: // case AppStoreType.xiaomi:
return await _openXiaomiStore(); // return await _openXiaomiStore();
case AppStoreType.oppo: // case AppStoreType.oppo:
return await _openOppoStore(); // return await _openOppoStore();
case AppStoreType.vivo: // case AppStoreType.vivo:
return await _openVivoStore(); // return await _openVivoStore();
case AppStoreType.honor: // case AppStoreType.honor:
return await _openHonorStore(); // return await _openHonorStore();
case AppStoreType.official: // case AppStoreType.official:
return await _openOfficialDownload(updateInfo.appInfo!.address!); // return await _openOfficialDownload(updateInfo.appInfo!.address!);
default: // default:
return await _openOfficialDownload(updateInfo.appInfo!.address!); return await _openOfficialDownload(updateInfo.appInfo!.address!);
} // }
} catch (e) { } catch (e) {
_logger.e('执行更新失败: $e'); _logger.e('执行更新失败: $e');
return false; return false;

119
lib/modules/login/controllers/login_controller.dart

@ -1,3 +1,5 @@
import 'dart:async';
import '../../../data/models/appconfig.dart'; import '../../../data/models/appconfig.dart';
import '../../../data/models/appconfig_model.dart'; import '../../../data/models/appconfig_model.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -815,54 +817,79 @@ class LoginController extends GetxController {
// 使用登陆请求服务器 // 使用登陆请求服务器
Future<void> requestLogin(Map params) async { Future<void> requestLogin(Map params) async {
Logger().d("请求后台数据login=$params"); try {
var response = await Api.login({ Logger().d("请求后台数据login=$params");
"mail": params["mail"], // 在Api.login调用时添加超时
"phone": params["phone"], var response = await Api.login({
"stype": params["stype"], "mail": params["mail"],
"vcode": params["vcode"], "phone": params["phone"],
"ttoken": params["ttoken"], "stype": params["stype"],
"phonemodel": _appVersion + _countryCode + _userChannel.toString(), "vcode": params["vcode"],
"phonemac": params["phonemac"], "ttoken": params["ttoken"],
"name": params["name"], "phonemodel": _appVersion + _countryCode + _userChannel.toString(),
"avatar": params["avatar"], "phonemac": params["phonemac"],
}); "name": params["name"],
if (response != null) { "avatar": params["avatar"],
Logger().d("请求后台数据login回复数据=$response"); }).timeout(
const Duration(seconds: 30), // 30秒超时
// final instance = await GetStorage(); onTimeout: () {
await _storage.write('loginInfo', jsonEncode(response)); throw TimeoutException('登录请求超时', const Duration(seconds: 30));
// 2. 将响应数据转换为User对象 },
try { );
Logger().d('响应数据: ${response.toString()}'); // 调试输出原始数据 if (response != null) {
Logger().d("请求后台数据login回复数据=$response");
if (response['token'].toString() != '') {
// 新增:检查 user 字段是否存在且类型正确 await _storage.write('loginInfo', jsonEncode(response));
// if (response.containsKey('data') && response['data'] is Map) {
final user = User.fromJson(response); try {
Logger().d('用户初始化成功: ${response['token'].toString()}'); Logger().d('响应数据: ${response.toString()}');
await _storage.write("logintoken", response['token'].toString());
// 存储到 SharedPreferences (仅存储用户数据) if (response['token'].toString() != '') {
//final prefs = await GetStorage(); final user = User.fromJson(response);
await _storage.write('user_info', user.toJson()); Logger().d('用户初始化成功: ${response['token'].toString()}');
await _storage.write("logintoken", response['token'].toString());
//获取app的配置信息 await _storage.write('user_info', user.toJson());
await getAppConfig();
Get.offAllNamed(Routes.pairing); // 获取app的配置信息
// } else { await getAppConfig();
// throw FormatException('API 响应缺少 user 字段'); Get.offAllNamed(Routes.pairing);
// } } else {
} else { throw Exception('接口返回错误: ${response['msg']}');
throw Exception('接口返回错误: ${response['msg']}'); }
} catch (e, stack) {
Logger().d('用户数据处理失败: $e');
Logger().d('堆栈跟踪: $stack');
Get.snackbar(
'error'.tr,
'userDataParseFailed'.tr, // 用户数据解析失败
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.1),
colorText: Colors.red,
);
} }
} catch (e, stack) { } else {
// 新增:打印堆栈跟踪 // API返回null的情况
Logger().d('用户数据处理失败: $e'); Get.snackbar(
Logger().d('堆栈跟踪: $stack'); 'error'.tr,
Get.snackbar('错误', '用户数据解析失败,请检查网络'); 'networkError'.tr, // 网络错误,请重试
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.1),
colorText: Colors.red,
);
} }
} catch (e) {
// Get.offAll(() => IndexWidget()); // 网络请求异常
Logger().e('登录请求失败: $e');
Get.snackbar(
'error'.tr,
'loginFailed'.tr, // 登录失败
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.1),
colorText: Colors.red,
);
} finally {
// 确保无论成功还是失败都重置加载状态
_isLoading.value = false;
} }
} }

17
lib/modules/login/views/login_view.dart

@ -13,12 +13,17 @@ class LoginView extends GetView<LoginController> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark; final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Scaffold( return GestureDetector(
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], onTap: () {
body: SafeArea( FocusScope.of(context).unfocus();
child: Obx(() => controller.viewState == LoginViewState.welcome },
? _buildWelcomeView(isDarkMode) child: Scaffold(
: _buildVerificationView(context, isDarkMode)), backgroundColor: isDarkMode ? Colors.black : Colors.grey[50],
body: SafeArea(
child: Obx(() => controller.viewState == LoginViewState.welcome
? _buildWelcomeView(isDarkMode)
: _buildVerificationView(context, isDarkMode)),
),
), ),
); );
} }

Loading…
Cancel
Save