import 'dart:async'; import 'dart:convert'; import 'dart:math'; import 'package:dating_touchme_app/config/env_config.dart'; import 'package:dating_touchme_app/controller/discover/room_controller.dart'; import 'package:dating_touchme_app/controller/overlay_controller.dart'; import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/pages/mine/login_page.dart'; import 'package:dating_touchme_app/rtc/rtc_manager.dart'; import 'package:dating_touchme_app/service/live_chat_message_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_http_sse/client/sse_client.dart'; import 'package:flutter_http_sse/enum/request_method_type_enum.dart'; import 'package:flutter_http_sse/model/sse_request.dart'; import 'package:flutter_http_sse/model/sse_response.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get_storage/get_storage.dart'; import 'package:location_plugin/location_plugin.dart'; import '../../network/home_api.dart'; import '../../model/home/marriage_data.dart'; class HomeController extends GetxController { // 推荐列表数据 final recommendFeed = [].obs; // 同城列表数据 final nearbyFeed = [].obs; final nearbyDisFeed = [].obs; final friendFootFeed = [].obs; // 推荐列表的加载状态和分页信息 final recommendIsLoading = false.obs; final recommendPage = 1.obs; final recommendHasMore = true.obs; final friendHasMore = true.obs; final friendIsLoading = false.obs; final friendPage = 1.obs; // 同城列表的加载状态和分页信息 final nearbyIsLoading = false.obs; final nearbyPage = 1.obs; final nearbyDisPage = 1.obs; final nearbyHasMore = true.obs; // 当前标签页索引 final selectedTabIndex = 0.obs; // 分页大小 final pageSize = 10; // 从GetX依赖注入中获取HomeApi实例 late final HomeApi _homeApi; final timelineTab = 0.obs; final RxnInt cityCode = RxnInt(); final RxnInt districtCode = RxnInt(); final _locationPlugin = LocationPlugin(); String _status = 'Idle'; String _cityStatus = 'Idle'; Map? _location; CityInfo? _cityInfo; final friendFootprintInfo = [].obs; Timer? _timer; @override void onInit() { super.onInit(); // 从全局依赖中获取HomeApi _homeApi = Get.find(); // 初始化时加载数据 loadInitialData(); getFriendFootprintInfo(); _timer = Timer.periodic(const Duration(minutes: 1), (timer) { getFriendFootprintInfo(); }); openSSE(); } final count = 3.obs; final request = SSERequest( requestType: RequestMethodType.get, url: "${EnvConfig.mainBaseUrl}dating-agency-sse/user/sse/connect", headers: { "Authorization": GetStorage().read('token'), "'X-APP-ID'": '50325897884795885' }, onData: (data) => print("Received: $data"), onError: (error) => print("Error: $error"), onDone: () => print("Stream closed"), retry: true, // Enables automatic reconnection ); final sseClient = SSEClient(); Timer? illTimer; openSSE() async { final Stream stream = sseClient.connect("connectionId", request); stream.listen( (SSEResponse response) { print("sseData: ${response.rawResponse}"); String raw = response.rawResponse; if (raw.startsWith("data:")) { String result = raw.substring(5); print(result); Map data = jsonDecode(result); print(data["data"]["illegalLabel"]); if (Get.isRegistered()) { final roomController = Get.find(); if(data["data"]["illegalHandle"] == 1){ if(data["data"]["illegalSubLabel"] != "WithoutFace"){ illTimer?.cancel(); RTCManager.instance.closeCamera(); illTimer = Timer(const Duration(minutes: 2), () { // 5 秒内没有被重新触发,才会执行这里 RTCManager.instance.reOpenCamera(); }); } // 隐藏 overlay if(!roomController.isDialogShowing.value){ SmartDialog.dismiss(); roomController.setDialogDismiss(true); SmartDialog.show( onDismiss: (){ roomController.setDialogDismiss(false); }, builder: (context) { return ClipRRect( borderRadius: BorderRadius.all(Radius.circular(16.w)), child: Material( color: Colors.white, child: Container( width: 311.w, height: 315.w, padding: EdgeInsets.only( top: 25.w, right: 25.w, left: 25.w ), child: Column( children: [ Image.asset( Assets.imagesLiveErrorIcon, width: 102.w, height: 102.w, ), SizedBox(height: 5.w,), Text( "系统提醒", textAlign: TextAlign.center, style: TextStyle( fontSize: 18.w, fontWeight: FontWeight.w700 ), ), SizedBox(height: 7.w,), Text( "你的行为涉嫌违反平台社区规范,请注意规范言行。多次违规将会受到限制功能、封禁账号等处罚,请文明交友,理性互动。", textAlign: TextAlign.center, style: TextStyle( fontSize: 14.w ), ), SizedBox(height: 14.w,), Container( width: 188.w, height: 40.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12.w)), color: const Color.fromRGBO(117, 98, 249, 1) ), child: Center( child: Text( "确认", style: TextStyle( fontSize: 14.w, color: Colors.white ), ), ), ).onTap(() { // RTCManager.instance.reOpenCamera(); // 隐藏 overlay SmartDialog.dismiss(); roomController.setDialogDismiss(false); }) ], ), ), ), ); }, ); } } else if(data["data"]["illegalHandle"] == 2){ SmartDialog.dismiss(); roomController.setDialogDismiss(true); Future.delayed(Duration(seconds: 3), () async { SmartDialog.dismiss(); final isNotBroadcaster = roomController.currentRole != CurrentRole.broadcaster; if (isNotBroadcaster) { await roomController.leaveChannel(); // 调用 LiveChatMessageService 处理结束直播消息 LiveChatMessageService.instance.handleEndLiveMessage(); roomController.logout(); Get.offAll(() => LoginPage()); } else { if(roomController.isClose.value) return; roomController.isClose.value = true; await roomController.leaveChannel(); SmartDialog.dismiss(); if (Get.isRegistered()) { final roomController = Get.find(); roomController.chatMessages.clear(); } // 如果还没有执行 pop,手动调用 Get.back() final OverlayController _overlayController = Get.find(); // 等待页面关闭后再显示小窗口,确保小窗口能正确显示 Future.delayed(const Duration(milliseconds: 200), () { _overlayController.hide(); roomController.isClose.value = false; }); roomController.logout(); Get.offAll(() => LoginPage()); } }); Timer? _timer; _timer = Timer.periodic(Duration(seconds: 1), (timer) { count.value --; update(); // 👇 你的终止条件 if (count.value == 0) { print("满足条件,停止执行"); timer.cancel(); // 停止 } }); SmartDialog.show( onDismiss: (){ roomController.setDialogDismiss(false); _timer?.cancel(); }, builder: (context) { return ClipRRect( borderRadius: BorderRadius.all(Radius.circular(16.w)), child: Material( color: Colors.white, child: Container( width: 311.w, height: 275.w, padding: EdgeInsets.only( top: 25.w, right: 25.w, left: 25.w ), child: Column( children: [ Image.asset( Assets.imagesLiveErrorIcon, width: 102.w, height: 102.w, ), SizedBox(height: 5.w,), Text( "账户封禁", textAlign: TextAlign.center, style: TextStyle( fontSize: 18.w, fontWeight: FontWeight.w700 ), ), SizedBox(height: 7.w,), Text( "你的账号因 涉嫌违规,已被封禁。", textAlign: TextAlign.center, style: TextStyle( fontSize: 14.w ), ), SizedBox(height: 14.w,), Obx((){ return Text( "${count.value}秒后返回到登录界面", textAlign: TextAlign.center, style: TextStyle( fontSize: 14.w ), ); }), ], ), ), ), ); }, ); } } } }, onError: (error) { print("SSE Error: $error"); sseClient.close(connectionId: "connectionId"); final random = Random(); int value = random.nextInt(8) + 3; Future.delayed(Duration(seconds: value), () async { openSSE(); }); }, onDone: () => print("SSE Connection Closed"), ); print("sse链接"); } @override void onClose() { super.onClose(); _timer?.cancel(); sseClient.close(connectionId: "connectionId"); } getFriendFootprintInfo() async { try { final response = await _homeApi.userGetFriendFootprintInfo(); if (response.data.isSuccess && response.data.data != null) { friendFootprintInfo.value = response.data.data?.profilePhotoList ?? []; update(); } else { // 响应失败,抛出异常 throw Exception(response.data.message ?? '获取数据失败'); } } catch(e){ print('足迹数据获取失败: $e'); SmartDialog.showToast('足迹数据获取失败'); rethrow; } } Future _fetchLocation() async { _status = 'Fetching location...'; try { print(1); print(await _locationPlugin.getCurrentLocation()); final location = await _locationPlugin.getCurrentLocation(); print(2); print(location); if (location == null) { _status = 'Location unavailable'; _cityStatus = 'Skip city lookup'; _cityInfo = null; return; } _location = location; _status = 'Success'; _cityStatus = 'Fetching city info...'; await _fetchCityInfo(location['latitude']!, location['longitude']!); } on PlatformException catch (e) { _status = 'Failed: ${e.code} ${e.message ?? ''}'.trim(); _cityStatus = 'Skip city lookup'; _cityInfo = null; } catch (e) { _status = 'Failed: $e'; _cityStatus = 'Skip city lookup'; _cityInfo = null; print(_status); print(_cityStatus); } } Future _fetchCityInfo(double latitude, double longitude) async { try { final info = await _locationPlugin.getCityInfo(latitude: latitude, longitude: longitude); print(info); _cityInfo = info; _cityStatus = info == null ? 'No city info' : 'Success'; cityCode.value = ((_cityInfo?.code ?? 0) ~/ 100) * 100; districtCode.value = _cityInfo?.code ?? 0; print(_cityInfo!.code); print("_cityInfo.code"); loadNearbyInitialData(); loadNearbyDisInitialData(); } on CityInfoLookupException catch (e) { _cityInfo = null; _cityStatus = 'Failed: ${e.code}'; } catch (e) { _cityInfo = null; _cityStatus = 'Failed: $e'; } } /// 加载初始数据(同时加载两个标签页的数据) void loadInitialData() async { // 并行加载两个标签页的数据 print(12121); await Future.wait([ loadRecommendInitialData(), ]); } /// 加载推荐列表初始数据 Future loadRecommendInitialData() async { if (recommendIsLoading.value) return; try { recommendIsLoading.value = true; recommendPage.value = 1; recommendHasMore.value = true; // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: 1, type: 0, ); // 重置并更新推荐列表 recommendFeed.clear(); recommendFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; // final int totalPages = result['pages'] ?? 1; final int totalPages = 100; recommendHasMore.value = currentPage < totalPages; print(recommendHasMore.value); } catch (e) { _handleError('获取推荐列表异常', e, '推荐列表加载失败,请稍后重试'); } finally { recommendIsLoading.value = false; } } /// 加载同城列表初始数据 Future loadNearbyInitialData() async { if(cityCode.value == null || cityCode.value == 0){ return; } if (nearbyIsLoading.value) return; try { nearbyIsLoading.value = true; nearbyPage.value = 1; nearbyHasMore.value = true; // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: 1, type: 1, code: cityCode.value ); // 重置并更新同城列表 nearbyFeed.clear(); nearbyFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; final int totalPages = result['pages'] ?? 1; nearbyHasMore.value = currentPage < totalPages; } catch (e) { _handleError('获取同城列表异常', e, '同城列表加载失败,请稍后重试'); } finally { nearbyIsLoading.value = false; } } /// 加载同城列表初始数据 Future loadNearbyDisInitialData() async { if(cityCode.value == null || cityCode.value == 0){ await _fetchLocation(); } else { if (nearbyIsLoading.value) return; try { nearbyIsLoading.value = true; nearbyPage.value = 1; nearbyHasMore.value = true; // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: 1, type: 2, code: districtCode.value ); // 重置并更新同城列表 nearbyDisFeed.clear(); nearbyDisFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; final int totalPages = result['pages'] ?? 1; nearbyHasMore.value = currentPage < totalPages; } catch (e) { _handleError('获取同城列表异常', e, '同城列表加载失败,请稍后重试'); } finally { nearbyIsLoading.value = false; } } } /// 加载推荐列表初始数据 Future loadFriendFootInitialData() async { if (friendIsLoading.value) return; try { friendIsLoading.value = true; friendPage.value = 1; friendHasMore.value = true; // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: 1, type: 5, ); // 重置并更新推荐列表 friendFootFeed.clear(); friendFootFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; // final int totalPages = result['pages'] ?? 1; final int totalPages = 100; friendHasMore.value = currentPage < totalPages; print(friendHasMore.value); } catch (e) { _handleError('获取推荐列表异常', e, '推荐列表加载失败,请稍后重试'); } finally { friendIsLoading.value = false; } } /// 加载更多数据 Future loadMoreData([int? tabIndex]) async { final targetTab = tabIndex ?? selectedTabIndex.value; if (targetTab == 0) { // 加载推荐列表更多数据 await loadRecommendMoreData(); } else { // 加载同城列表更多数据 await loadNearbyMoreData(); } } /// 加载推荐列表更多数据 Future loadRecommendMoreData() async { if (recommendIsLoading.value || !recommendHasMore.value) return; try { recommendIsLoading.value = true; // final nextPage = recommendPage.value + 1; final nextPage = recommendPage.value; print('推荐列表加载更多 - 当前页: ${recommendPage.value}, 下一页: $nextPage'); // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: nextPage, type: 0, ); // 更新页码 recommendPage.value = nextPage; // 更新推荐列表 recommendFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] as int; // final int totalPages = result['pages'] as int; final int totalPages = 100; recommendHasMore.value = currentPage < totalPages; print('推荐列表加载更多完成 - 当前页: $currentPage, 总页数: $totalPages, 还有更多: ${recommendHasMore.value}'); } catch (e) { _handleError('加载推荐更多异常', e, '加载更多失败'); } finally { recommendIsLoading.value = false; } } /// 加载同城列表更多数据 Future loadNearbyMoreData() async { if (nearbyIsLoading.value || !nearbyHasMore.value) return; try { nearbyIsLoading.value = true; // final nextPage = nearbyPage.value + 1; final nextPage = nearbyPage.value; print('同城列表加载更多 - 当前页: ${nearbyPage.value}, 下一页: $nextPage'); // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: nextPage, type: 1, code: cityCode.value ); // 更新页码 nearbyPage.value = nextPage; // 更新同城列表 nearbyFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] as int; final int totalPages = result['pages'] as int; nearbyHasMore.value = currentPage < totalPages; print('同城列表加载更多完成 - 当前页: $currentPage, 总页数: $totalPages, 还有更多: ${nearbyHasMore.value}'); } catch (e) { _handleError('加载同城更多异常', e, '加载更多失败'); } finally { nearbyIsLoading.value = false; } } /// 加载同城列表更多数据 Future loadNearbyDisMoreData() async { if (nearbyIsLoading.value || !nearbyHasMore.value) return; try { nearbyIsLoading.value = true; // final nextPage = nearbyPage.value + 1; final nextPage = nearbyPage.value; print('同城列表加载更多 - 当前页: ${nearbyPage.value}, 下一页: $nextPage'); // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: nextPage, type: 2, code: districtCode.value ); // 更新页码 nearbyDisPage.value = nextPage; // 更新同城列表 nearbyDisFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] as int; final int totalPages = result['pages'] as int; nearbyHasMore.value = currentPage < totalPages; print('同城列表加载更多完成 - 当前页: $currentPage, 总页数: $totalPages, 还有更多: ${nearbyHasMore.value}'); } catch (e) { _handleError('加载同城更多异常', e, '加载更多失败'); } finally { nearbyIsLoading.value = false; } } /// 加载推荐列表更多数据 Future loadFriendFootMoreData() async { if (friendIsLoading.value || !friendHasMore.value) return; try { friendIsLoading.value = true; // final nextPage = recommendPage.value + 1; final nextPage = friendPage.value; print('推荐列表加载更多 - 当前页: ${friendPage.value}, 下一页: $nextPage'); // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: nextPage, type: 5, ); // 更新页码 friendPage.value = nextPage; // 更新推荐列表 friendFootFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] as int; // final int totalPages = result['pages'] as int; final int totalPages = 100; friendHasMore.value = currentPage < totalPages; print('推荐列表加载更多完成 - 当前页: $currentPage, 总页数: $totalPages, 还有更多: ${friendHasMore.value}'); } catch (e) { _handleError('加载推荐更多异常', e, '加载更多失败'); } finally { friendIsLoading.value = false; } } /// 刷新数据 Future refreshData([int? tabIndex]) async { final targetTab = tabIndex ?? selectedTabIndex.value; if (targetTab == 0) { // 刷新推荐列表 await refreshRecommendData(); } else { // 刷新同城列表 await refreshNearbyData(); } } /// 刷新推荐列表数据 Future refreshRecommendData() async { if (recommendIsLoading.value) return; try { recommendIsLoading.value = true; recommendPage.value = 1; recommendHasMore.value = true; // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: 1, type: 0, ); // 更新推荐列表 recommendFeed.clear(); recommendFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; // final int totalPages = result['pages'] ?? 1; final int totalPages = 100; recommendHasMore.value = currentPage < totalPages; } catch (e) { _handleError('刷新推荐数据异常', e, '刷新失败,请稍后重试'); } finally { recommendIsLoading.value = false; } } /// 刷新同城列表数据 Future refreshNearbyData() async { if (nearbyIsLoading.value) return; try { nearbyIsLoading.value = true; nearbyPage.value = 1; nearbyHasMore.value = true; // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: 1, type: 1, code: cityCode.value ); // 更新同城列表 nearbyFeed.clear(); nearbyFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; final int totalPages = result['pages'] ?? 1; nearbyHasMore.value = currentPage < totalPages; } catch (e) { _handleError('刷新同城数据异常', e, '刷新失败,请稍后重试'); } finally { nearbyIsLoading.value = false; } } /// 刷新同城列表数据 Future refreshNearbyDisData() async { if (nearbyIsLoading.value) return; try { nearbyIsLoading.value = true; nearbyPage.value = 1; nearbyHasMore.value = true; // 获取同城数据 (type=1) final result = await _fetchMarriageData( pageNum: 1, type: 2, code: districtCode.value ); // 更新同城列表 nearbyDisFeed.clear(); nearbyDisFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; final int totalPages = result['pages'] ?? 1; nearbyHasMore.value = currentPage < totalPages; } catch (e) { _handleError('刷新同城数据异常', e, '刷新失败,请稍后重试'); } finally { nearbyIsLoading.value = false; } } /// 刷新推荐列表数据 Future refreshFriendData() async { if (friendIsLoading.value) return; try { friendIsLoading.value = true; friendPage.value = 1; friendHasMore.value = true; // 获取推荐数据 (type=0) final result = await _fetchMarriageData( pageNum: 1, type: 5, ); // 更新推荐列表 friendFootFeed.clear(); friendFootFeed.addAll(result['records']); // 根据返回的分页信息判断是否还有更多数据 final int currentPage = result['current'] ?? 1; // final int totalPages = result['pages'] ?? 1; final int totalPages = 100; friendHasMore.value = currentPage < totalPages; } catch (e) { _handleError('刷新推荐数据异常', e, '刷新失败,请稍后重试'); } finally { friendIsLoading.value = false; } } /// 设置当前标签页 void setSelectedTabIndex(int index) async { print('Setting selected tab index to: $index'); selectedTabIndex.value = index; // 确保UI能够更新 update(); if(index == 2 && nearbyFeed.isEmpty){ print(cityCode.value == null || cityCode.value == 0); print("cityCode.value == null || cityCode.value == 0"); if(cityCode.value == null || cityCode.value == 0){ _fetchLocation(); } else { loadNearbyInitialData(); } } } /// 获取当前标签页的列表数据 List getFeedListByTab(int tabIndex) { return tabIndex == 0 ? List.from(recommendFeed) : List.from(nearbyFeed); } /// 私有方法:获取婚姻数据(统一的数据获取逻辑) /// 返回包含records(数据列表)、current(当前页)、pages(总页数)的Map Future> _fetchMarriageData({ required int pageNum, required int type, int? code }) async { try { if(type != 5){ print('_fetchMarriageData - pageNum: $pageNum, pageSize: $pageSize, type: $type'); // 调用API获取数据 var response = await _homeApi.getMarriageList( pageNum: pageNum, pageSize: pageSize, type: type, cityCode: type == 1 ? code : null, districtCode: type == 2 ? code : null, ); if (response.data.isSuccess) { final paginatedData = response.data.data; // 检查data是否为空 if (paginatedData == null) { return { 'records': [], 'current': pageNum, 'pages': 1, 'total': 0, 'size': pageSize, }; } // data 是 PaginatedResponse,直接使用其属性 // records 中的每个项是 dynamic,需要转换为 MarriageData final allRecords = paginatedData.records .map((item) => MarriageData.fromJson(item as Map)) .toList(); // 过滤掉直播类型的项 final records = allRecords.where((item) => !item.isLive).toList(); print('_fetchMarriageData 返回 - 请求页码: $pageNum, 返回当前页: ${paginatedData.current}, 总页数: ${paginatedData.pages}, 原始记录数: ${allRecords.length}, 过滤后记录数: ${records.length}'); return { 'records': records, 'current': paginatedData.current, 'pages': paginatedData.pages, 'total': paginatedData.total, 'size': paginatedData.size, }; } else { // 响应失败,抛出异常 throw Exception(response.data.message); } } else { print('_fetchMarriageData - pageNum: $pageNum, pageSize: $pageSize, type: $type'); // 调用API获取数据 var response = await _homeApi.userPageFriendFootprint( pageNum: pageNum, pageSize: pageSize, ); if (response.data.isSuccess) { final paginatedData = response.data.data; // 检查data是否为空 if (paginatedData == null) { return { 'records': [], 'current': pageNum, 'pages': 1, 'total': 0, 'size': pageSize, }; } paginatedData.records.forEach((e){ e["liveStreaming"] = true; e["isLiveChannelId"] = e["channelId"]; }); // data 是 PaginatedResponse,直接使用其属性 // records 中的每个项是 dynamic,需要转换为 MarriageData final allRecords = paginatedData.records .map((item) => MarriageData.fromJson(item as Map)) .toList(); // 过滤掉直播类型的项 final records = allRecords.where((item) => !item.isLive).toList(); print('_fetchMarriageData 返回 - 请求页码: $pageNum, 返回当前页: ${paginatedData.current}, 总页数: ${paginatedData.pages}, 原始记录数: ${allRecords.length}, 过滤后记录数: ${records.length}'); return { 'records': records, 'current': paginatedData.current, 'pages': paginatedData.pages, 'total': paginatedData.total, 'size': paginatedData.size, }; } else { // 响应失败,抛出异常 throw Exception(response.data.message); } } } catch (e) { // 向上抛出异常,让调用方处理 rethrow; } } /// 私有方法:统一的错误处理 void _handleError(String logMessage, dynamic error, String toastMessage) { // 打印错误日志 print('$logMessage: $error'); // 显示错误提示 SmartDialog.showToast(toastMessage); } }