Przeglądaj źródła

网络请求异步的封装并测试通过

liukai 1 rok temu
rodzic
commit
512349db76

+ 90 - 37
lib/api/api_provider.dart

@@ -1,6 +1,7 @@
 import 'dart:io';
 
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:ftrecruiter/api/http_result.dart';
 import 'package:get/get.dart';
 import 'package:ftrecruiter/api/interceptors/auth_interceptor.dart';
 import 'package:ftrecruiter/api/interceptors/log_res_interceptor.dart';
@@ -16,10 +17,10 @@ typedef NetErrorCallback = Function(int? code, String? msg);
 
 enum HttpMethod { GET, POST }
 
-//基类的Api封装
+/// 网络请求相关封装
 class ApiProvider extends GetConnect {
-  //Get请求封装
-  Future<void> requestNetwork(
+  /// 默认简单的请求封装,回调的方式
+  Future<void> requestNetEasy(
     String url, {
     HttpMethod? method,
     Map<String, String>? headers,
@@ -29,39 +30,10 @@ class ApiProvider extends GetConnect {
     NetSuccessListCallback<List<dynamic>>? onSuccessList,
     NetErrorCallback? onError,
   }) async {
-    //封装参数
-    Future<Response> req;
-
-    if (method != null && method == HttpMethod.POST) {
-      var map = <String, dynamic>{};
-
-      if (query != null || paths != null) {
-        if (query != null) {
-          map.addAll(query);
-        }
-
-        if (paths != null) {
-          paths.forEach((key, value) {
-            final file = File(value);
-            map[key] = MultipartFile(
-              file.readAsBytesSync(),
-              filename: "file",
-            );
-          });
-        }
-      }
-
-      var form = FormData(map);
-
-      Log.d("Post请求FromData参数,fields:${form.fields.toString()} files:${form.files.toString()}");
-      //以Post-Body的方式上传
-      req = post(url, form, headers: headers);
-    } else {
-      //以Get-Params的方式上传
-      req = get(url, headers: headers, query: query);
-    }
+    //根据参数封装请求
+    var req = generateRequest(method, query, paths, url, headers);
 
-    //开始真正请求
+    //开始请求
     final startTime = DateTime.now().millisecond;
     var result = await req;
     final endTime = DateTime.now().millisecond;
@@ -103,9 +75,90 @@ class ApiProvider extends GetConnect {
         onError(result.statusCode, result.statusText);
       }
       //吐司网络请求错误
-      SmartDialog.compatible
-          .showToast("Request Network Error :${result.statusCode}  ${result.statusText}");
+      SmartDialog.compatible.showToast("Request Network Error :${result.statusCode}  ${result.statusText}");
+    }
+  }
+
+  /// 网络请求异步的Result封装
+  Future<HttpResult> requestNetResult(
+    String url, {
+    HttpMethod? method,
+    Map<String, String>? headers,
+    Map<String, dynamic>? query,
+    Map<String, String>? paths,
+  }) async {
+    //根据参数封装请求
+    var req = generateRequest(method, query, paths, url, headers);
+
+    //开始请求
+    final startTime = DateTime.now().millisecond;
+    var result = await req;
+    final endTime = DateTime.now().millisecond;
+
+    if (!AppConstant.inProduction) {
+      final duration = endTime - startTime;
+      Log.d('网络请求耗时 $duration 毫秒, 响应内容 ${result.body}}');
     }
+
+    if (result.statusCode == 200) {
+      //网络请求正确之后获取正常的Json-Map
+      Map<String, dynamic> jsonMap = result.body;
+
+      //判断成功与失败
+      int code = jsonMap['code'];
+      if (code == 200) {
+        if (jsonMap['data'] is List<dynamic>) {
+          //成功->返回数组
+          return HttpResult(isSuccess: true, listJson: jsonMap['data'],);
+        } else {
+          //成功->返回对象
+          return HttpResult(isSuccess: true, dataJson: jsonMap['data']);
+        }
+      } else {
+        //失败->返回Api错误
+        return HttpResult(isSuccess: false, errorCode: jsonMap['code'], errorMsg: jsonMap['message']);
+      }
+    } else {
+      //失败->返回网络请求错误
+      return HttpResult(isSuccess: false, errorCode: result.statusCode, errorMsg: result.statusText);
+    }
+  }
+
+  ///生成请求体
+  Future<Response> generateRequest(HttpMethod? method, Map<String, dynamic>? query, Map<String, String>? paths,
+      String url, Map<String, String>? headers) async {
+    Future<Response> req;
+
+    if (method != null && method == HttpMethod.POST) {
+      var map = <String, dynamic>{};
+
+      if (query != null || paths != null) {
+        if (query != null) {
+          map.addAll(query);
+        }
+
+        if (paths != null) {
+          paths.forEach((key, value) {
+            final file = File(value);
+            map[key] = MultipartFile(
+              file.readAsBytesSync(),
+              filename: "file",
+            );
+          });
+        }
+      }
+
+      var form = FormData(map);
+
+      Log.d("Post请求FromData参数,fields:${form.fields.toString()} files:${form.files.toString()}");
+      //以Post-Body的方式上传
+      req = post(url, form, headers: headers);
+    } else {
+      //默认以Get-Params的方式上传
+      req = get(url, headers: headers, query: query);
+    }
+
+    return req;
   }
 
   @override

+ 100 - 57
lib/api/api_repository.dart

@@ -1,7 +1,9 @@
 import 'dart:io';
 
 import 'package:ftrecruiter/api/api_provider.dart';
+import 'package:ftrecruiter/api/http_result.dart';
 import 'package:ftrecruiter/comm/constants/api_constants.dart';
+import 'package:ftrecruiter/comm/utils/log_utils.dart';
 import 'package:ftrecruiter/entity/response/UserLogin.dart';
 import 'package:ftrecruiter/entity/response/hotel_login.dart';
 import 'package:ftrecruiter/entity/response/industry_data.dart';
@@ -13,57 +15,83 @@ class ApiRepository {
 
   ApiRepository({required this.apiProvider});
 
-  //获取服务器时间
-  void getServerTime({NetSuccessCallback<ServerTime>? success, NetErrorCallback? onError}) {
+  // //获取服务器时间
+  // void getServerTime({NetSuccessCallback<ServerTime>? success, NetErrorCallback? onError}) {
+  //   Map<String, String> headers = {};
+  //   headers["Accept"] = "application/x.yyjobs-api.v1+json";
+  //
+  //   //获取数据和处理数据的逻辑放在这里
+  //   apiProvider.requestNetEasy(ApiConstants.apiServiceTime, headers: headers, onSuccess: (json) {
+  //     var serverTime = ServerTime.fromJson(json);
+  //     if (success != null) {
+  //       success(serverTime);
+  //     }
+  //   }, onError: onError);
+  // }
+
+  //获取服务器时间2
+  Future<HttpResult<ServerTime?>> getServerTime2() async {
     Map<String, String> headers = {};
     headers["Accept"] = "application/x.yyjobs-api.v1+json";
 
-    //获取数据和处理数据的逻辑放在这里
-    apiProvider.requestNetwork(ApiConstants.apiServiceTime, headers: headers, onSuccess: (json) {
-      var serverTime = ServerTime.fromJson(json);
-      if (success != null) {
-        success(serverTime);
-      }
-    }, onError: onError);
+    //网络请求获取原始数据
+    final result = await apiProvider.requestNetResult(ApiConstants.apiServiceTime, headers: headers);
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = ServerTime.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<ServerTime?>(data: data);
+    }
+    return result.convert<ServerTime?>();
   }
 
-  //获取用户信息
-  void getUserProfile({NetSuccessCallback<UserProfile>? success, NetErrorCallback? onError}) {
+  /// 获取行业列表
+  Future<HttpResult<IndustryData?>> getIndustryList2() async {
     Map<String, String> headers = {};
     headers["Accept"] = "application/x.yyjobs-api.v1+json";
 
-    apiProvider.requestNetwork(ApiConstants.apiUserProfile, headers: headers, onSuccess: (json) {
-      var userProfile = UserProfile.fromJson(json);
-      if (success != null) {
-        success(userProfile);
-      }
-    }, onError: onError);
-  }
+    final result = await apiProvider.requestNetResult(ApiConstants.apiIndustryList, headers: headers);
 
-  //获取行业列表
-  void getIndustryList(
-      {NetSuccessListCallback<List<IndustryData?>>? success, NetErrorCallback? onError}) {
-    Map<String, String> headers = {};
-    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+    if (result.isSuccess) {
+      final jsonList = result.getListJson();
 
-    apiProvider.requestNetwork(ApiConstants.apiIndustryList, headers: headers,
-        onSuccessList: (jsonList) {
       //获取List数据 需要转换一次
-      var industryList = jsonList.map((value) {
+      var list = jsonList?.map((value) {
         if (value is Map<String, dynamic>) {
           return IndustryData.fromJson(value);
         } else {
           return null;
         }
       }).toList();
-      if (success != null) {
-        success(industryList);
-      }
-    }, onError: onError);
+
+      return result.convert<IndustryData?>(list: list);
+    }
+
+    return result.convert<IndustryData>();
+  }
+
+  //获取用户信息
+  Future<HttpResult<UserProfile?>> getUserProfile(String? token) async {
+    Map<String, String> headers = {};
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+    headers["Authorization"] = "bearer$token";
+
+    var result = await apiProvider.requestNetResult(ApiConstants.apiUserProfile, headers: headers);
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = UserProfile.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<UserProfile?>(data: data);
+    }
+    return result.convert<UserProfile?>();
   }
 
   //用户登陆
-  void userLogin({NetSuccessCallback<UserLogin>? success, NetErrorCallback? onError}) {
+  Future<HttpResult<UserLogin?>> userLogin() async {
     Map<String, String> headers = {};
     headers["Accept"] = "application/x.yyjobs-api.v1+json";
 
@@ -72,49 +100,64 @@ class ApiRepository {
     params["password"] = "12345678";
     params["registration_id"] = "1234";
 
-    apiProvider.requestNetwork(ApiConstants.apiUserLogin,
-        method: HttpMethod.POST, headers: headers, query: params, onSuccess: (json) {
-      var userLogin = UserLogin.fromJson(json);
-      if (success != null) {
-        success(userLogin);
-      }
-    }, onError: onError);
+    var result = await apiProvider.requestNetResult(ApiConstants.apiUserLogin,
+        method: HttpMethod.POST, headers: headers, query: params);
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = UserLogin.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<UserLogin?>(data: data);
+    }
+    return result.convert<UserLogin?>();
   }
 
   //更新用户信息
-  void userProfileUpdate(String? token,
-      {NetSuccessCallback<UserLogin>? success, NetErrorCallback? onError}) {
+  Future<HttpResult<UserLogin?>> userProfileUpdate(String? token) async {
     Map<String, String> headers = {};
     headers["Accept"] = "application/x.yyjobs-api.v12+json";
     headers["Authorization"] = "bearer$token";
 
     Map<String, String> params = {};
-    params["mobile_no"] = "+8618571458165";
+    params["mobile_no"] = "+8618571458166";
     params["verification_code"] = "123456 ";
     params["nick_name"] = "test liukai";
 
     Map<String, String> paths = {};
-    paths['news_feed_avatar'] =
-        '/data/user/0/com.hongyegroup.ftrecruiter/app_flutter/test_avatar.jpeg';
-
-    apiProvider.requestNetwork(ApiConstants.apiUpdateProfile,
-        method: HttpMethod.POST, headers: headers, query: params, paths: paths, onSuccess: (json) {
-      var userLogin = UserLogin.fromJson(json);
-      if (success != null) {
-        success(userLogin);
-      }
-    }, onError: onError);
+    paths['news_feed_avatar'] = '/data/user/0/com.hongyegroup.ftrecruiter/app_flutter/test_avatar.jpeg';
+
+    var result = await apiProvider.requestNetResult(
+      ApiConstants.apiUpdateProfile,
+      method: HttpMethod.POST,
+      headers: headers,
+      query: params,
+      paths: paths,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = UserLogin.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<UserLogin?>(data: data);
+    }
+    return result.convert<UserLogin?>();
   }
 
-  //酒店登陆
-  void hotelLogin({NetSuccessCallback<HotelLogin>? success, NetErrorCallback? onError}) {
+  //用户登陆(回调的方式)
+  void userLoginEasy({NetSuccessCallback<UserLogin>? success, NetErrorCallback? onError}) {
+    Map<String, String> headers = {};
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
     Map<String, String> params = {};
-    params["auth_code"] = "DAP3VDG";
-    params["device_mac"] = "020000000000";
+    params["nric_no"] = "+8618571458166";
+    params["password"] = "12345678";
+    params["registration_id"] = "1234";
 
-    apiProvider.requestNetwork(ApiConstants.apiHotelLogin, method: HttpMethod.POST, query: params,
+    apiProvider.requestNetEasy(ApiConstants.apiUserLogin, method: HttpMethod.POST, headers: headers, query: params,
         onSuccess: (json) {
-      var userLogin = HotelLogin.fromJson(json);
+      var userLogin = UserLogin.fromJson(json);
       if (success != null) {
         success(userLogin);
       }

+ 58 - 0
lib/api/http_result.dart

@@ -0,0 +1,58 @@
+import 'package:ftrecruiter/comm/utils/log_utils.dart';
+
+class HttpResult<T> {
+  HttpResult({required this.isSuccess, dynamic dataJson, List<dynamic>? listJson, this.errorCode, this.errorMsg}) {
+    this._dataJson = dataJson;
+    this._listJson = listJson;
+  }
+
+  //是否成功
+  bool isSuccess = false;
+
+  //成功的数据(Json数据)
+  dynamic _dataJson;
+  List<dynamic>? _listJson;
+
+  //成功的数据(真正的数据)
+  T? data;
+  List<T>? list;
+
+  //失败的数据
+  int? errorCode;
+  String? errorMsg;
+
+  Map<String, dynamic>? getDataJson() {
+    if (_dataJson is Map<String, dynamic>) {
+      return _dataJson as Map<String, dynamic>;
+    }
+    return null;
+  }
+
+  List<dynamic>? getListJson() {
+    return _listJson;
+  }
+
+  /// 设置真正的数据对象
+  void setData(T data) {
+    this.data = data;
+  }
+
+  void setList(List<T> list) {
+    this.list = list;
+  }
+
+  /// 基本类型转换为指定的泛型类型
+  HttpResult<T> convert<T>({T? data, List<T>? list}) {
+    var result = HttpResult<T>(
+        isSuccess: this.isSuccess,
+        dataJson: this._dataJson,
+        listJson: this._listJson,
+        errorCode: this.errorCode,
+        errorMsg: this.errorMsg);
+
+    result.data = data;
+    result.list = list;
+
+    return result;
+  }
+}

+ 6 - 2
lib/app_binding.dart

@@ -2,11 +2,15 @@ import 'package:get/get.dart';
 import 'package:ftrecruiter/api/api_provider.dart';
 import 'package:ftrecruiter/api/api_repository.dart';
 
-//异步注入构造方法中的对象 用于Api网络请求相关的注入
+///异步注入构造方法中的对象 用于Api网络请求相关的注入
+///主要是在App初始化的时候就注入到依赖注入的池里面,并单例持久化
 class AppBinding extends Bindings {
   @override
   void dependencies() async {
     Get.put(ApiProvider(), permanent: true);
-    Get.put(ApiRepository(apiProvider: Get.find()), permanent: true);
+    // Get.lazyPut(ApiRepository(apiProvider: Get.find()), permanent: true);
+    Get.lazyPut<ApiRepository>(() => ApiRepository(apiProvider: Get.find()));
+
+
   }
 }

+ 0 - 1
lib/comm/constants/api_constants.dart

@@ -2,7 +2,6 @@
 class ApiConstants {
   //基础域名
   static const baseUrl = 'http://yyjobs-api-dev.guabean.com';
-  // static const baseUrl = 'http://smart-pass-dev.casualabour.com';
 
   //服务器时间
   static const apiServiceTime = "/index.php/api/employee/extra/time";

+ 42 - 22
lib/modules/zdemo/DemoPage.dart

@@ -30,20 +30,33 @@ class DemoPage extends StatelessWidget {
             children: [
               CommonWidget.rowHeight(height: 15),
 
+              GetBuilder<DemoController>(builder: (controller) {
+                return Text(obtainTextStr(controller.status) ?? "-");
+              }),
+
               //第一个按钮
               TextButton(
-                style: ButtonStyle(
-                  minimumSize: MaterialStateProperty.all<Size>(const Size(200, 45)), // 设置最小宽度和高度
-                  backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent),
-                ),
-                onPressed: () {
-                  SmartDialog.compatible.showToast("默认的原生按钮");
-                },
-                child: const Text(
-                  '默认的原生按钮',
-                  style: TextStyle(fontSize: 16, color: Colors.white),
-                ),
-              ),
+                  style: ButtonStyle(
+                    minimumSize: MaterialStateProperty.all<Size>(const Size(200, 45)), // 设置最小宽度和高度
+                    backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent),
+                  ),
+                  onPressed: () {
+                    controller.increase();
+
+                    // controller.getServerTime2();
+
+                    // controller.getIndustry2();
+
+                    // controller.complicatedFetch();
+
+                    controller.getUserInfo();
+                  },
+                  child: Obx(() {
+                    return Text(
+                      "当前数量:${controller.count}",
+                      style: const TextStyle(fontSize: 16, color: Colors.white),
+                    );
+                  })),
 
               CommonWidget.rowHeight(height: 15),
 
@@ -53,17 +66,13 @@ class DemoPage extends StatelessWidget {
                 text: "My Button的封装按钮",
                 backgroundColor: ColorConstants.gray,
                 onPressed: () {
-
                   controller.getLocalFile('test_avatar.jpeg').then((File file) {
                     // 在此处处理文件对象
-
-                   var list =  file.readAsBytesSync();
+                    var list = file.readAsBytesSync();
                     SmartDialog.compatible.showToast("file:${file.parent}");
 
                     Log.e("file:${file.path}  list:$list");
                   });
-
-
                 },
                 radius: 15,
                 enableOverlay: false,
@@ -74,18 +83,29 @@ class DemoPage extends StatelessWidget {
               CommonWidget.rowHeight(height: 15),
 
               MyButton(
-                text: "自定义圆角按钮",
-                backgroundColor: DarkThemeUtil.multiColors(
-                    ColorConstants.dividerColor, darkColor: Colors.deepOrange),
+                text: "顺序调用接口,先登录后获取",
+                backgroundColor: DarkThemeUtil.multiColors(ColorConstants.dividerColor, darkColor: Colors.deepOrange),
                 radius: 20,
                 elevation: 5.0,
                 onPressed: () {
-                  controller.getServerTime();
+                  controller.getUserInfo();
                 },
               ),
-
             ],
           )),
     );
   }
+
+  String? obtainTextStr(RxStatus status) {
+    if (status.isLoading) {
+      return "Loading...";
+    } else if (status.isSuccess) {
+      return "Success";
+    } else if (status.isEmpty) {
+      return "Empty";
+    } else if (status.isError) {
+      return status.errorMessage;
+    }
+    return "";
+  }
 }

+ 76 - 42
lib/modules/zdemo/demo_controller.dart

@@ -1,4 +1,6 @@
 import 'dart:io';
+import 'package:ftrecruiter/api/http_result.dart';
+import 'package:ftrecruiter/entity/response/industry_data.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:flustars/flustars.dart';
 import 'package:flutter/material.dart';
@@ -8,67 +10,77 @@ import 'package:ftrecruiter/comm/utils/log_utils.dart';
 import 'package:ftrecruiter/entity/response/server_time.dart';
 import 'package:get/get.dart';
 
-class DemoController extends GetxController with StateMixin<ServerTime> {
+class DemoController extends GetxController with StateMixin<dynamic> {
   DemoController({required this.apiRepository});
 
-  final ApiRepository apiRepository;
+  var count = 0.obs;
 
-  final registerEmailController = TextEditingController();
+  void increase() => ++count;
 
-  //调用接口,获取服务器时间
-  void getServerTime() {
-    //获取服务器时间
-    // apiRepository.getServerTime(success: (serverTime) {
-    //   Log.d("data:$serverTime");
-    //   change(serverTime, status: RxStatus.success());
-    // }, onError: (code, msg) {
-    //   Log.d("data-error:$code $msg");
-    //   change(null, status: RxStatus.empty());
-    // });
+  final ApiRepository apiRepository;
 
-    //获取用户信息
-    // apiRepository.getUserProfile(success: (userProfile) {
-    //   Log.d("user-profile-success - memberId:${userProfile.memberId}");
-    //   SmartDialog.showToast(
-    //       "get user profile success , memberId:${userProfile.memberId}");
-    // }, onError: (code, msg) {
-    //   Log.d("user-profile-error:$code $msg");
-    // });
+  final registerEmailController = TextEditingController();
 
-    //获取行业列表
-    // apiRepository.getIndustryList(success: (list) {
-    //   Log.d("industry-success list length: ${list.length}");
-    // }, onError: (code, msg) {
-    //   Log.d("industry-error:$code $msg");
-    // });
+  //调用接口
+  Future<void> getUserInfo() async {
+    change(null, status: RxStatus.loading());
 
     //测试Post请求,用户登陆
-    apiRepository.userLogin(success: (userLogin) {
+    final result = await apiRepository.userLogin();
 
-      SmartDialog.showToast("Token: ${userLogin.token}");
+    if (result.isSuccess) {
+      final token = result.data?.token;
 
+      if (token != null) {
+        final profile = await apiRepository.getUserProfile(token);
 
-      apiRepository.userProfileUpdate(userLogin.token,success: (userLogin) {
+        if (profile.isSuccess == true) {
+          final nickName = profile.data?.nickName;
 
-        SmartDialog.showToast("更新用户信息成功");
+          SmartDialog.compatible.showToast("当前登录的用户为:$nickName");
 
-      },onError: (code, msg) {
+          change(null, status: RxStatus.success());
+        }
+      }
+    } else {
+      final errorMsg = result.errorMsg;
+      change(null, status: RxStatus.error(errorMsg));
+    }
 
-        SmartDialog.showToast("更新用户信息错误: $code $msg");
+    //测试Post请求,用户登陆
+    // apiRepository.userLoginEasy(success: (userLogin) {
+    //
+    //   SmartDialog.showToast("Token: ${userLogin.token}");
+
+    // apiRepository.userProfileUpdate(userLogin.token,success: (userLogin) {
+    //
+    //   SmartDialog.showToast("更新用户信息成功");
+    //
+    // },onError: (code, msg) {
+    //
+    //   SmartDialog.showToast("更新用户信息错误: $code $msg");
+    //
+    // });
 
-      });
+    // }, onError: (code, msg) {
+    //   Log.d("用户登陆-error:$code $msg");
+    // });
+  }
 
+  Future<void> getServerTime2() async {
+    final result = await apiRepository.getServerTime2();
 
-    }, onError: (code, msg) {
-      Log.d("用户登陆-error:$code $msg");
-    });
+    if (result.isSuccess) {
+      SmartDialog.compatible.showToast("获取时间:${result.data?.timestamps}");
+    } else {}
+  }
 
-    // apiRepository.hotelLogin(success: (hotelLogin) {
-    //   SmartDialog.showToast("Token: ${hotelLogin.token}");
-    // }, onError: (code, msg) {
-    //   SmartDialog.showToast("酒店登陆-error:$code $msg");
-    // });
+  Future<void> getIndustry2() async {
+    final result = await apiRepository.getIndustryList2();
 
+    if (result.isSuccess) {
+      SmartDialog.compatible.showToast("获取行列列表:${result.list?.toString()}");
+    } else {}
   }
 
   Future<File> getLocalFile(String fileName) async {
@@ -76,4 +88,26 @@ class DemoController extends GetxController with StateMixin<ServerTime> {
     return File('${directory.path}/$fileName');
   }
 
+  /// 并发执行
+  Future<void> complicatedFetch() async {
+    //由于是单线程的,对并发的逻辑并不好,不如Kotlin
+
+    // 等待所有的Future对象都完成
+    List<dynamic> results = await Future.wait([apiRepository.getServerTime2(), apiRepository.getIndustryList2()]);
+
+    int? timestamps;
+    List<IndustryData?>? industries;
+
+    for (var future in results) {
+      if (future is HttpResult<ServerTime?>) {
+        final serverTime = future;
+        timestamps = serverTime.data?.timestamps;
+      } else if (future is HttpResult<IndustryData?>) {
+        final industryList = future;
+        industries = industryList.list;
+      }
+    }
+
+    SmartDialog.compatible.showToast("并发完成的数据 行业数量:${industries?.length} 当前时间:$timestamps");
+  }
 }