Browse Source

Merge commit 'b28855cc844eecf9f4e359f6180ddf7c935dcae6' into lxm

newdev_shunjiawei
lxm 2 years ago
parent
commit
dbe6c9605d
  1. 26
      lib/core/bindings/initial_binding.dart
  2. 19
      lib/data/models/user_Info.dart
  3. 3
      lib/data/services/network/api.dart
  4. 2
      lib/data/services/network/dio_manager.dart
  5. 2
      lib/main.dart
  6. 128
      lib/modules/login/controllers/login_controller.dart
  7. 11
      lib/modules/settings/controllers/settings_controller.dart
  8. 105
      lib/modules/splash/controllers/splash_controller.dart

26
lib/core/bindings/initial_binding.dart

@ -13,10 +13,10 @@ class InitialBinding extends Bindings {
@override
void dependencies() {
Logger.warning('InitialBinding dependencies');
// 语言管理器(需要最先初始化)
Get.put<LanguageManager>(LanguageManager(), permanent: true);
//初始化语音工厂
Get.put<SpeechFactory>(SpeechFactory(), permanent: true);
Get.find<SpeechFactory>().initialize(initialType: SpeechServiceType.azure);
@ -25,17 +25,25 @@ class InitialBinding extends Bindings {
Get.lazyPut<ChatHistoryService>(() => ChatHistoryService(), fenix: true);
// 火山翻译服务
Get.lazyPut<VolcanoTranslationService>(() => VolcanoTranslationService(), fenix: true);
Get.lazyPut<VolcanoTranslationService>(() => VolcanoTranslationService(),
fenix: true);
// 火山AI服务
Get.lazyPut<VolcanoAIService>(() => VolcanoAIService(), fenix: true);
// 注意:VoiceInteractionService 在 HomeController 中初始化
Get.lazyPut<VoiceInteractionService>(() => VoiceInteractionService(), fenix: true);
// 经典蓝牙服务
Get.lazyPut<ClassicBluetoothService>(() => ClassicBluetoothService(), fenix: true);
Get.lazyPut<VoiceInteractionService>(() => VoiceInteractionService(),
fenix: true);
// 经典蓝牙服务
Get.lazyPut<ClassicBluetoothService>(() => ClassicBluetoothService(),
fenix: true);
// // 语言管理器(需要最先初始化)
// Get.put<LoginService>(LoginService(), permanent: true);
// await LoginService().FirebaseInit();
// print('资源FirebaseInit加载错误: 完成');
// await LoginService().WeChatInit();
// print('资源FWeChatInit加载错误: 完成');
}
}
}

19
lib/data/models/user_Info.dart

@ -53,11 +53,13 @@ class User {
factory User.fromJson(Map<String, dynamic> json) {
// 修复1:安全获取嵌套的 user 字段
final userData = json['data']['user'] as Map<String, dynamic>?; // 允许空值
final token = json['data']['token'] as String? ?? '';
final userData = json['user'] as Map<String, dynamic>?; // 允许空值
//final token = json['data']['token'] as String? ?? '';
//final token = '';
// 更新单例实例
return _instance = User._(
token: token as String? ?? '',
token: '',
//token: token as String? ?? '',
name: (userData?['name'] as String?) ?? '默认名称', // 提供默认值
uid: (userData?['uid'] as String?) ?? '',
avatar: (userData?['avatar'] as String?) ?? '',
@ -79,10 +81,10 @@ class User {
factory User.fronTokenJson(Map<String, dynamic> json) {
// 修复1:安全获取嵌套的 user 字段
final userData = json['user'] as Map<String, dynamic>?; // 允许空值
final token = '';
print("数据获取fronTokenJson${userData}");
// 更新单例实例
return _instance = User._(
token: token as String? ?? '',
token: '',
name: (userData?['name'] as String?) ?? '默认名称', // 提供默认值
uid: (userData?['uid'] as String?) ?? '',
avatar: (userData?['avatar'] as String?) ?? '',
@ -122,11 +124,4 @@ class User {
// 'facebookopenid': facebookopenid,
}
};
// 获取用户名的快捷方法
static String getname() => instance.name;
static String getdeviceInfo() => instance.deviceid;
static String getuserId() => instance.uid;
static String getstanding() => "";
static String getnavatar() => instance.avatar;
}

3
lib/data/services/network/api.dart

@ -4,7 +4,7 @@ import 'nw_method.dart';
class Api {
// 登录
static login([params]) {
print("请求后台数据params=${params}");
print("请求后台数据login params=${params}");
return DioManager().request(
NWMethod.post,
'/api/home/user_sgin',
@ -22,7 +22,6 @@ class Api {
}
static tokenlogin([params]) {
print("请求后台数据params=${params}");
return DioManager().request(
NWMethod.post,
'/api/home/user_getinfo',

2
lib/data/services/network/dio_manager.dart

@ -21,7 +21,7 @@ class DioManager {
dio = Dio(options);
//fdp
// dio.interceptors.add(AuthInterceptor());
dio.interceptors.add(AuthInterceptor());
}
// 请求,返回参数为 T

2
lib/main.dart

@ -24,7 +24,7 @@ void main() async {
// 初始化环境变量
await dotenv.load();
LoginService();
//LoginService.FirebaseInit();
// 设置窗口大小(仅在 macOS 下生效)
if (Platform.isMacOS) {
const double width = 375.0;

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

@ -67,7 +67,6 @@ class LoginController extends GetxController {
_contactValue.value = contactController.text;
_formatDisplayContact();
_startCountdown();
_sendVerificationCode();
}
@ -133,7 +132,7 @@ class LoginController extends GetxController {
_contactValue.value = contactController.text;
_formatDisplayContact();
_viewState.value = LoginViewState.verification;
_startCountdown();
_sendVerificationCode();
}
@ -185,14 +184,26 @@ class LoginController extends GetxController {
Future<void> _sendVerificationCode() async {
// 这里应该是实际发送验证码的逻辑
// 为了演示,我们只是模拟发送
var response = await Api.getCode({
"addr": contactController.text,
"vtype": 0,
});
if (response != null) {
print("请求后台数据验证码params=${response}");
//短信已发送
//EasyLoading.showInfo('codeSend'.tr);
if (isEmialContactController() || isPhoneContactController()) {
_startCountdown();
var response = await Api.getCode({
"addr": contactController.text,
"vtype": 0,
});
if (response != null) {
print("请求后台数据验证码params=${response}");
//短信已发送
//EasyLoading.showInfo('codeSend'.tr);
}
} else {
Get.snackbar(
'提示',
'请正确的手机号码或邮箱',
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.1),
colorText: Colors.red,
);
return;
}
}
@ -205,6 +216,7 @@ class LoginController extends GetxController {
// 更新验证码输入
void updateVerificationCode(int index, String value) {
print("updateVerificationCode=${index}${value}");
if (index >= 0 && index < 4) {
var newList = [..._verificationCode];
newList[index] = value;
@ -217,40 +229,32 @@ class LoginController extends GetxController {
_verificationCode.value = ['', '', '', ''];
}
// 检查验证码是否完整
bool isVerificationCodeComplete() {
return !_verificationCode.contains('');
// 检查邮箱格式
bool isEmialContactController() {
// 检查每个元素是否为单个字母或数字字符
final text = contactController.text;
return (text.length > 5 &&
RegExp(r'^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
.hasMatch(text)) ||
(RegExp(r'^[z0-9]$').hasMatch(text));
}
Future<void> getLoginToken() async {
// 使用正确语法创建请求头
var response = await Api.tokenlogin();
if (response != null) {
if (response?["code"] == null) {
final user = User.fronTokenJson(response);
await _storage.write(
'user', jsonEncode(user.toJson())); // 使用 user.toJson()
Get.offAllNamed(Routes.pairing);
}
} else {
login();
}
// 检查手机号码格式
bool isPhoneContactController() {
// 检查每个元素是否为单个字母或数字字符
final text = contactController.text;
return RegExp(r'^[0-9]+$').hasMatch(text);
}
// 检查验证码是否完整
bool isVerificationCodeComplete() {
// 检查每个元素是否为单个字母或数字字符
final text = verificationCodeController.text;
return text.length == 4 && RegExp(r'^[A-Za-z0-9]$').hasMatch(text);
}
// 登录
Future<void> login() async {
// 暂时关闭验证码验证
// if (!isVerificationCodeComplete()) {
// Get.snackbar(
// '提示',
// '请输入完整的验证码',
// snackPosition: SnackPosition.TOP,
// backgroundColor: Colors.red.withOpacity(0.1),
// colorText: Colors.red,
// );
// return;
// }
_isLoading.value = true;
try {
@ -260,16 +264,16 @@ class LoginController extends GetxController {
switch (loginType) {
case 0 || 1:
{
// if (!isVerificationCodeComplete()) {
// Get.snackbar(
// '提示',
// '请输入完整的验证码',
// snackPosition: SnackPosition.TOP,
// backgroundColor: Colors.red.withOpacity(0.1),
// colorText: Colors.red,
// );
// break;
// }
if (!isVerificationCodeComplete()) {
Get.snackbar(
'提示',
'请输入完整的验证码',
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.1),
colorText: Colors.red,
);
break;
}
requestLogin({
"mail": contactController.text,
"phone": "",
@ -425,21 +429,21 @@ class LoginController extends GetxController {
try {
print('响应数据: ${response.toString()}'); // 调试输出原始数据
if (response['code'].toString() == '0') {
if (response['token'].toString() != '') {
// 新增:检查 user 字段是否存在且类型正确
if (response.containsKey('data') && response['data'] is Map) {
final user = User.fromJson(response);
print('用户初始化成功: ${user.token}');
await _storage.write("logintoken", user.token);
// 存储到 SharedPreferences (仅存储用户数据)
//final prefs = await GetStorage();
await _storage.write(
'user', jsonEncode(user.toJson())); // 使用 user.toJson()
Get.offAllNamed(Routes.pairing);
} else {
throw FormatException('API 响应缺少 user 字段');
}
// if (response.containsKey('data') && response['data'] is Map) {
final user = User.fromJson(response);
print('用户初始化成功: ${response['token'].toString()}');
await _storage.write("logintoken", response['token'].toString());
// 存储到 SharedPreferences (仅存储用户数据)
//final prefs = await GetStorage();
await _storage.write(
'user', jsonEncode(user.toJson())); // 使用 user.toJson()
Get.offAllNamed(Routes.pairing);
// } else {
// throw FormatException('API 响应缺少 user 字段');
// }
} else {
throw Exception('接口返回错误: ${response['msg']}');
}

11
lib/modules/settings/controllers/settings_controller.dart

@ -60,11 +60,11 @@ class SettingsController extends GetxController {
];
//用户信息
static const String userKey='user_info';
static const String userKey = 'user_info';
//final _storage=GetStorage();
final ImagePicker _picker=ImagePicker();
final Rx<User> userInfo=User.instance.obs;//使用单例实例
final ImagePicker _picker = ImagePicker();
final Rx<User> userInfo = User.instance.obs; //使用单例实例
@override
void onInit() {
super.onInit();
@ -103,7 +103,7 @@ class SettingsController extends GetxController {
maxHeight: 800,
imageQuality: 85,
);
if (image != null) {
userInfo.update((user) {
if (user != null) {
@ -205,6 +205,7 @@ class SettingsController extends GetxController {
void signOut() {
// 在此实现退出登录逻辑
_storage.write("logintoken", "");
Get.offAllNamed('/login');
}
}

105
lib/modules/splash/controllers/splash_controller.dart

@ -1,50 +1,49 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../../../data/models/user_Info.dart';
import '../../../routes/app_routes.dart';
import '../../../core/themes/theme_service.dart';
import '../../../data/services/network/api.dart';
class SplashController extends GetxController {
final GetStorage _storage = GetStorage();
// 进度条动画控制
final _loadingProgress = 0.0.obs;
double get loadingProgress => _loadingProgress.value;
// 版本号
final String version = 'v1.0.0';
// 资源加载状态
final _isResourceLoaded = false.obs;
bool get isResourceLoaded => _isResourceLoaded.value;
// 版本号
final String version = 'v1.0.0';
// 主题服务
final ThemeService _themeService = ThemeService();
@override
void onInit() {
super.onInit();
// 确保页面先渲染,再执行其他操作
WidgetsBinding.instance.addPostFrameCallback((_) {
// 启动进度条动画
_startLoadingAnimation();
// 异步加载应用资源
_loadAppResources();
});
}
// 进度条动画
// 进度条动画(持续2秒)
void _startLoadingAnimation() {
// 模拟0.5秒的加载进度
Timer.periodic(const Duration(milliseconds: 5), (timer) {
const totalDuration = 2000; // 动画总时长2秒
const steps = totalDuration ~/ 50; // 40次更新(50ms间隔)
final stepValue = 1.0 / steps;
Timer.periodic(const Duration(milliseconds: 50), (timer) {
if (_loadingProgress.value < 1.0) {
_loadingProgress.value += 0.01;
_loadingProgress.value += stepValue;
} else {
timer.cancel();
// 当进度条动画完成且资源加载完毕时,跳转到登录页面
if (_isResourceLoaded.value) {
_navigateToLogin();
}
_checkNavigateCondition();
}
});
}
@ -52,37 +51,63 @@ class SplashController extends GetxController {
// 异步加载应用资源
Future<void> _loadAppResources() async {
try {
// 在这里可以添加应用初始化需要的资源加载
// 例如:预加载图片、初始化数据库、加载配置等
// 模拟耗时操作
await Future.delayed(const Duration(milliseconds: 100));
// 模拟资源加载(如API配置、本地缓存等)
await Future.delayed(const Duration(milliseconds: 1500));
// TODO: 在此处添加实际的资源加载代码
// 实际资源加载代码
// await _loadImages();
// await _initDatabase();
// 标记资源加载完成
_isResourceLoaded.value = true;
// 如果进度条已经走完,则跳转到登录页面
if (_loadingProgress.value >= 1.0) {
_navigateToLogin();
}
_checkNavigateCondition();
} catch (e) {
// 处理资源加载错误
// 即使加载失败,也应该允许用户继续使用应用
_isResourceLoaded.value = true;
// 记录错误日志
Get.snackbar('错误', '资源加载失败,请检查网络连接');
_isResourceLoaded.value = true; // 允许用户继续使用
print('资源加载错误: $e');
}
}
// 跳转到登录页面
void _navigateToLogin() {
// 添加一个小延迟,确保UI完全渲染
Future.delayed(const Duration(milliseconds: 200), () {
Get.offAllNamed(Routes.login);
});
// 检查跳转条件
void _checkNavigateCondition() {
if (_loadingProgress.value >= 1.0 && _isResourceLoaded.value) {
_navigateToLogin();
}
}
// 获取登录Token并跳转
Future<void> _navigateToLogin() async {
final isLoggedIn = await getLoginToken();
if (isLoggedIn) {
// Get.offAllNamed(Routes.login); // 跳转到登录页
// Get.offAllNamed(Routes.home); // 跳转到主页
Get.offAllNamed(Routes.pairing);
} else {
Get.offAllNamed(Routes.login); // 跳转到登录页
}
}
Future<bool> getLoginToken() async {
try {
print('getLoginToken:进来了');
//if (User.getname() != "") {
final response = await Api.tokenlogin();
print('getLoginToken: $response');
if (response == null) return false;
if (response['user'] != '') {
print('getLoginToken:进来了');
// 根据API设计调整
final user = User.fromJson(response);
// 存储用户信息(示例)
await _storage.write('user_info', user.toJson());
return true;
}
//return true;
//}
return false;
} catch (e) {
print('Token获取失败: $e');
return false;
}
}
// fdp挑转登陆
}

Loading…
Cancel
Save