From baee5dba83eaaa493067eb728b22dfe8b45e530f Mon Sep 17 00:00:00 2001 From: userGyl Date: Thu, 8 Jan 2026 15:33:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=AD=E5=BF=83=EF=BC=8C?= =?UTF-8?q?=E5=BE=85=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/lib/main.dart | 3 + .../lib/pages/c_page/message/controller.dart | 141 ++++++++++++------ ln_jq_app/lib/pages/c_page/message/model.dart | 2 +- .../lib/pages/c_page/mine/controller.dart | 35 +++++ ln_jq_app/lib/pages/c_page/mine/view.dart | 21 ++- 5 files changed, 145 insertions(+), 57 deletions(-) diff --git a/ln_jq_app/lib/main.dart b/ln_jq_app/lib/main.dart index 2b21ea5..31692b4 100644 --- a/ln_jq_app/lib/main.dart +++ b/ln_jq_app/lib/main.dart @@ -5,6 +5,7 @@ import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; import 'package:ln_jq_app/common/token_interceptor.dart'; import 'package:ln_jq_app/storage_service.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'common/styles/theme.dart'; import 'pages/home/view.dart'; @@ -47,6 +48,8 @@ void main() async { fallbackLocale: Locale('zh', 'CN'), supportedLocales: [Locale('zh', 'CN')], localizationsDelegates: const [ + //pull_to_refresh + RefreshLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, diff --git a/ln_jq_app/lib/pages/c_page/message/controller.dart b/ln_jq_app/lib/pages/c_page/message/controller.dart index b4b899f..f9fc7cc 100644 --- a/ln_jq_app/lib/pages/c_page/message/controller.dart +++ b/ln_jq_app/lib/pages/c_page/message/controller.dart @@ -1,16 +1,17 @@ -import 'package:get/get.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; +import 'package:ln_jq_app/common/model/base_model.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; + import 'model.dart'; class MessageController extends GetxController { final RefreshController refreshController = RefreshController(initialRefresh: false); final RxList messageList = [].obs; int _pageNum = 1; - final int _pageSize = 10; + final int _pageSize = 20; - // 模拟所有已读状态,实际应根据接口判断 - final RxBool allRead = false.obs; + // 是否所有已读状态 + final RxBool allRead = false.obs; @override void onInit() { @@ -19,45 +20,58 @@ class MessageController extends GetxController { } Future _loadData({bool isRefresh = false}) async { - if (isRefresh) { - _pageNum = 1; - } else { - _pageNum++; - } + final int targetPage = isRefresh ? 1 : _pageNum + 1; try { - // 模拟请求延迟 - await Future.delayed(const Duration(milliseconds: 500)); - - // 模拟数据 (请替换为实际接口请求) - // var response = await HttpService.to.post('message/list', data: {'pageNum': _pageNum, 'pageSize': _pageSize}); - - List newData = List.generate(10, (index) { - int id = (_pageNum - 1) * _pageSize + index; + final Map requestData = { + 'appFlag': 1, + 'pageNum': targetPage, + 'pageSize': _pageSize, + }; + + final response = await HttpService.to.get( + 'appointment/unread_notice/page', + params: requestData, + ); + + if (response == null) { + throw Exception("Response is null"); + } + + final result = BaseModel.fromJson(response.data); + + if (result.code != 0) { + throw Exception(result.message ?? "Business error"); + } + + final recordsList = result.data?["records"] as List? ?? []; + + final List newData = recordsList.map((e) { return MessageModel( - id: id.toString(), - title: '加氢预约失败通知', - content: '1月6日14时30分-1月6日15时30分,北京朝阳加氢站加氢预约失败。原因:设备维护', - createTime: '刚刚', - isRead: index % 3 == 0 ? 1 : 0, + id: e['id']?.toString() ?? '', + title: e['noticeTitle'] ?? '', + content: e['noticeContent'] ?? '', + createTime: e['createTime'] ?? '', + isRead: int.tryParse(e['isRead']?.toString() ?? '0') ?? 0, ); - }); + }).toList(); if (isRefresh) { messageList.assignAll(newData); - refreshController.refreshCompleted(); + _pageNum = 1; // 只有成功了才重置页码 } else { - if (newData.isEmpty) { - refreshController.loadNoData(); - } else { - messageList.addAll(newData); - refreshController.loadComplete(); + messageList.addAll(newData); + if (newData.isNotEmpty) { + _pageNum++; // 只有成功且有数据才+1 } } - - _checkAllRead(); + _updateRefreshState(isRefresh, newData.length); + + // 检查是否全部已读 + _checkAllRead(); } catch (e) { + Logger.d("加载失败: $e"); // 建议加上日志 if (isRefresh) { refreshController.refreshFailed(); } else { @@ -66,24 +80,48 @@ class MessageController extends GetxController { } } + /// 处理 RefreshController 状态 + void _updateRefreshState(bool isRefresh, int count) { + if (isRefresh) { + refreshController.refreshCompleted(); + // 如果刷新后的数据量小于 pageSize,说明没有更多数据了 + if (count < _pageSize) { + refreshController.loadNoData(); + } else { + // 必须重置 footer 状态,否则之前如果是 NoData 状态无法再加载 + refreshController.resetNoData(); + } + } else { + if (count == 0) { + refreshController.loadNoData(); + } else { + refreshController.loadComplete(); + } + } + } + void onRefresh() => _loadData(isRefresh: true); + void onLoading() => _loadData(isRefresh: false); // 标记全部已读 void markAllRead() async { showLoading('正在标记...'); try { - // await HttpService.to.post('message/readAll'); - await Future.delayed(const Duration(milliseconds: 500)); - - for (var msg in messageList) { - msg.isRead = 1; + final response = await HttpService.to.post('appointment/unread_notice/read/all'); + if (response != null) { + final result = BaseModel.fromJson(response.data); + if (result.code == 0) { + for (var msg in messageList) { + msg.isRead = 0; + } + messageList.refresh(); + allRead.value = true; + + dismissLoading(); + showSuccessToast('全部已读'); + } } - messageList.refresh(); - allRead.value = true; - - dismissLoading(); - showSuccessToast('全部已读'); } catch (e) { dismissLoading(); showErrorToast('操作失败'); @@ -92,15 +130,22 @@ class MessageController extends GetxController { // 标记单条已读(弹窗显示时调用) void markRead(MessageModel message) async { - if (message.isRead == 1) return; - - // await HttpService.to.post('message/read', data: {'id': message.id}); - message.isRead = 1; - messageList.refresh(); - _checkAllRead(); + if (message.isRead == 0) return; + + final response = await HttpService.to.post( + '/appointment/unread_notice/read/${message.id}', + ); + if (response != null) { + final result = BaseModel.fromJson(response.data); + if (result.code == 0) { + message.isRead = 0; + messageList.refresh(); + _checkAllRead(); + } + } } void _checkAllRead() { - allRead.value = messageList.every((msg) => msg.isRead == 1); + allRead.value = messageList.every((msg) => msg.isRead == 0); } } diff --git a/ln_jq_app/lib/pages/c_page/message/model.dart b/ln_jq_app/lib/pages/c_page/message/model.dart index d0a5ce0..82f542b 100644 --- a/ln_jq_app/lib/pages/c_page/message/model.dart +++ b/ln_jq_app/lib/pages/c_page/message/model.dart @@ -3,7 +3,7 @@ class MessageModel { final String title; final String content; final String createTime; - int isRead; // 0: 未读, 1: 已读 + int isRead; // 0: 已读, 1: 未读 MessageModel({ required this.id, diff --git a/ln_jq_app/lib/pages/c_page/mine/controller.dart b/ln_jq_app/lib/pages/c_page/mine/controller.dart index c873609..64070bb 100644 --- a/ln_jq_app/lib/pages/c_page/mine/controller.dart +++ b/ln_jq_app/lib/pages/c_page/mine/controller.dart @@ -31,6 +31,7 @@ class MineController extends GetxController with BaseControllerMixin { } String rate = ""; + String rating = ""; String accident = ""; String historyBreakRules = ""; String vin = ""; @@ -38,6 +39,7 @@ class MineController extends GetxController with BaseControllerMixin { String violationTotal = "0"; String violationScore = "0"; String violationDispose = "0"; + bool isNotice = false; void renderData() async { if (StorageService.to.hasVehicleInfo) { @@ -56,6 +58,8 @@ class MineController extends GetxController with BaseControllerMixin { _fetchCompletionRate(), // 请求1:完成率 _fetchAccidentCount(), // 请求2:事故数 _fetchBreakRulesCount(), // 请求3:违章数 + _rating(), // 司机评分 + _msgNotice(), // 红点消息 ]); } catch (e, stackTrace) { showErrorToast("加载数据失败,请稍后重试 $e"); @@ -65,6 +69,37 @@ class MineController extends GetxController with BaseControllerMixin { } } + Future _msgNotice() async { + final Map requestData = { + 'appFlag': 1, + 'isRead': 1, + 'pageNum': 1, + 'pageSize': 5, + }; + final response = await HttpService.to.get( + 'appointment/unread_notice/page', + params: requestData, + ); + if (response != null) { + final result = BaseModel.fromJson(response.data); + if (result.code == 0 && result.data != null) { + int total = result.data["total"] ?? 0; + isNotice = total > 0; + } + } + } + + Future _rating() async { + final response = await HttpService.to.get('appointment/rating/driver'); + + if (response != null) { + final result = BaseModel.fromJson(response.data); + if (result.code == 0 && result.data != null) { + rating = result.data.toString(); + } + } + } + Future _fetchCompletionRate() async { final response = await HttpService.to.get( 'appointment/orderAddHyd/driverAppointmentCompletionRate?phone=${StorageService.to.phone}', diff --git a/ln_jq_app/lib/pages/c_page/mine/view.dart b/ln_jq_app/lib/pages/c_page/mine/view.dart index e1e27ab..b28b3bc 100644 --- a/ln_jq_app/lib/pages/c_page/mine/view.dart +++ b/ln_jq_app/lib/pages/c_page/mine/view.dart @@ -91,17 +91,19 @@ class MinePage extends GetView { backgroundColor: Colors.grey[100], padding: const EdgeInsets.all(8), ), - icon: const Badge( + icon: Badge( // label: Text('3'), // 如果你想显示数字,就加 label - smallSize: 8, // 红点的大小 - backgroundColor: Colors.red, // 红点颜色 + smallSize: 8, + // 红点的大小 + backgroundColor: controller.isNotice ? Colors.red : Colors.white, + // 红点颜色 child: Icon( Icons.notifications_outlined, color: Colors.black87, size: 25, ), ), - ) + ), ], ), ), @@ -157,14 +159,14 @@ class MinePage extends GetView { fit: StackFit.expand, children: [ CircularProgressIndicator( - value: 10, // 假设得分80% + value: (double.tryParse(controller.rating) ?? 0) / 10, strokeWidth: 8, backgroundColor: Colors.grey[200], valueColor: AlwaysStoppedAnimation(Colors.blue), ), Center( child: Text( - '10', + controller.rating, style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, @@ -329,7 +331,10 @@ class MinePage extends GetView { // 如果加载完成且有数据 if (snapshot.hasData) { - return TextX.labelSmall("当前版本: ${snapshot.data}",color: Colors.black54,); + return TextX.labelSmall( + "当前版本: ${snapshot.data}", + color: Colors.black54, + ); } // 错误处理 @@ -338,7 +343,7 @@ class MinePage extends GetView { ), ), ], - ) + ), ], ), ),