From 79fe3257b5a803279b73e09a0d93be462a4c76ef Mon Sep 17 00:00:00 2001 From: userGyl Date: Wed, 28 Jan 2026 17:59:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ln_jq_app/lib/pages/b_page/site/view.dart | 398 +++++++++++++++------- 1 file changed, 279 insertions(+), 119 deletions(-) diff --git a/ln_jq_app/lib/pages/b_page/site/view.dart b/ln_jq_app/lib/pages/b_page/site/view.dart index b1a77db..fa61cc7 100644 --- a/ln_jq_app/lib/pages/b_page/site/view.dart +++ b/ln_jq_app/lib/pages/b_page/site/view.dart @@ -52,7 +52,7 @@ class SitePage extends GetView { GestureDetector( onTap: () { Get.to( - () => HistoryPage(), + () => HistoryPage(), arguments: {'stationName': controller.name}, ); }, @@ -78,6 +78,7 @@ class SitePage extends GetView { ], ), + SizedBox(height: 35.h,), //第三部分 Container( padding: const EdgeInsets.all(15), @@ -141,7 +142,10 @@ class SitePage extends GetView { borderRadius: BorderRadius.vertical(bottom: Radius.circular(20)), ), padding: EdgeInsets.only( - top: MediaQuery.of(context).padding.top + 10, + top: MediaQuery + .of(context) + .padding + .top + 10, left: 20, right: 20, bottom: 25, @@ -200,7 +204,8 @@ class SitePage extends GetView { const SizedBox(height: 25), Row( children: [ - _buildStatBox("剩余氢量", "remaining quantity", controller.leftHydrogen, "kg"), + _buildStatBox( + "剩余氢量", "remaining quantity", controller.leftHydrogen, "kg"), SizedBox(width: 4.w), _buildStatBox( "今日加氢量", @@ -364,7 +369,8 @@ class SitePage extends GetView { children: [ Icon(Icons.inventory_2_outlined, size: 80, color: Colors.grey[300]), const SizedBox(height: 16), - const Text('暂无预约数据', style: TextStyle(fontSize: 16, color: Colors.black54)), + const Text( + '暂无预约数据', style: TextStyle(fontSize: 16, color: Colors.black54)), const SizedBox(height: 8), const Text( '点击右上角刷新按钮获取最新数据', @@ -377,137 +383,292 @@ class SitePage extends GetView { /// 构建“有预约数据”的列表视图 Widget _buildReservationListView() { - return Container( - color: Colors.white, - child: ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - // 因为外层已有滚动,这里禁用内部滚动 - itemCount: controller.reservationList.length, - padding: const EdgeInsets.all(12.0), - itemBuilder: (context, index) { - final item = controller.reservationList[index]; - // 调用新的方法来构建每一项 - return _buildReservationItem(index, item); - }, - separatorBuilder: (context, index) => const SizedBox(height: 12), // 列表项之间的间距 - ), + return ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + // 因为外层已有滚动,这里禁用内部滚动 + itemCount: controller.reservationList.length, + itemBuilder: (context, index) { + final item = controller.reservationList[index]; + // 调用新的方法来构建每一项 + return _buildReservationItem(index, item); + }, + separatorBuilder: (context, index) => const SizedBox(height: 0), // 列表项之间的间距 ); } Widget _buildReservationItem(int index, ReservationModel item) { + const kPrimaryGreen = Color(0xFF006D35); // 深绿 + const kLineColor = Color(0xFFE0E6ED); // 线条颜色 + + return IntrinsicHeight( + // 保证左侧竖线能跟右侧内容高度对齐 + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 1. 左侧样式区域(竖线 + 圆点) + SizedBox( + width: 20, + child: Column( + children: [ + // 顶部的装饰圆点 + Container( + margin: EdgeInsets.only(top: 3.w), + width: 8, + height: 8, + decoration: BoxDecoration( + color: kPrimaryGreen.withOpacity(0.5), + shape: BoxShape.circle, + ), + ), + // 延伸的竖线 + Expanded(child: Container(width: 1, color: kLineColor)), + ], + ), + ), + // 2. 右侧内容区域(时间 + 卡片数据) + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 10.w, bottom: 8.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 时间显示 + Text( + item.time, // 格式如 "09:00 - 10:00" + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.bold, + color: Color(0xFF333333), + ), + ), + const SizedBox(height: 10), + + // 数据卡片 + _buildInfoCard(item), + ], + ), + ), + ), + ], + ), + ); + } + + /// 右侧具体数据卡片 + Widget _buildInfoCard(ReservationModel item) { return Container( + padding: EdgeInsets.only(left: 16.w, top: 8.5, bottom: 8.5, right: 16.w), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(8.0), - border: Border.all(color: Colors.grey[200]!, width: 1.0), + borderRadius: BorderRadius.circular(16), + border: Border.all(color: const Color(0xFFF0F0F0)), boxShadow: [ BoxShadow( - color: Colors.grey.withOpacity(0.1), - spreadRadius: 1, - blurRadius: 3, - offset: const Offset(0, 2), + color: Colors.black.withOpacity(0.04), + blurRadius: 10, + offset: const Offset(0, 4), ), ], ), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 顶部:序号、车牌号、状态 - Padding( - padding: const EdgeInsets.fromLTRB(8, 12, 16, 12), - child: Row( - children: [ - // 序号 - Container( - width: 24, - height: 24, - alignment: Alignment.center, - decoration: const BoxDecoration( - color: Colors.blue, - shape: BoxShape.circle, - ), - child: Text( - "${index + 1}", - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), + // 车牌与状态标签 + Row( + children: [ + Text( + item.plateNumber, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.bold, + color: Color(0xFF333333), ), - const SizedBox(width: 8), - const Icon(Icons.directions_car, color: Colors.black54), - const SizedBox(width: 4), - // 车牌号 - Expanded( - child: Text( - item.plateNumber, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: AppTheme.themeColor, - ), - ), - ), - // 状态标签 - _buildStatusChip(item.status), - ], - ), - ), - const Divider(height: 1), - // 中部:详细信息 - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), - child: Column( - children: [ - _buildDetailRow( - Icons.local_gas_station, - '加氢量', - item.amount, - valueColor: Colors.red, - ), - const SizedBox(height: 8), - _buildDetailRow(Icons.access_time, '预约时间', item.time), - const SizedBox(height: 8), - _buildDetailRow(Icons.person, '联系人', item.contactPerson), - const SizedBox(height: 8), - _buildDetailRow( - Icons.phone, - '联系电话', - item.contactPhone, - valueColor: AppTheme.themeColor, - ), - ], - ), - ), - // 底部:操作按钮 (仅在待处理时显示) - if (item.status == ReservationStatus.pending) - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), - child: Row( - children: [ - Expanded( - child: ElevatedButton( - onPressed: () => controller.confirmReservation(item.id), - style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), - child: const Text('确认'), - ), - ), - const SizedBox(width: 16), - Expanded( - child: ElevatedButton( - onPressed: () => controller.rejectReservation(item.id), - style: ElevatedButton.styleFrom(backgroundColor: Colors.red), - child: const Text('拒绝'), - ), - ), - ], ), + const SizedBox(width: 8), + _buildStatusTag(item.status), + Spacer(), + Text( + "预约量:${item.amount}", + style: TextStyle( + color: Color(0xFF00A870), + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const SizedBox(height: 8), + // 联系信息 + Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "${item.contactPerson} | ${item.contactPhone}", + style: TextStyle( + color: Color(0xFF999999), + fontSize: 12.sp, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + + //操作按钮(仅在待处理状态显示) + if (item.status == ReservationStatus.pending) ...[ + const SizedBox(height: 15), + const Divider(height: 1, color: Color(0xFFF5F5F5)), + const SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + _buildSmallButton( + "拒绝", + isOutline: true, + onTap: () { + controller.rejectReservation(item.id); + }, + ), + const SizedBox(width: 12), + _buildSmallButton( + "确认", + isOutline: false, + onTap: () { + controller.confirmReservation(item.id); + }, + ), + ], ), + ], ], ), ); } + /// 通用小按钮 + Widget _buildSmallButton(String text, { + required bool isOutline, + required VoidCallback onTap, + }) { + const kPrimaryGreen = Color(0xFF006D35); + const kDangerRed = Color(0xFFFF7D7D); + + return GestureDetector( + onTap: onTap, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + decoration: BoxDecoration( + color: isOutline ? Colors.white : kPrimaryGreen, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: isOutline ? kDangerRed : kPrimaryGreen), + ), + child: Text( + text, + style: TextStyle( + color: isOutline ? kDangerRed : Colors.white, + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } + + /// 状态标签构建(带圆角和浅色背景) + Widget _buildStatusTag(ReservationStatus status) { + Color textColor; + Color bgColor; + String text; + + switch (status) { + case ReservationStatus.pending: + text = "待加氢"; + textColor = const Color(0xFFFE9E62); // 橘色 + bgColor = const Color(0xFFFFF2E9); + break; + case ReservationStatus.completed: // 假设已加氢状态 + text = "已加氢"; + textColor = const Color(0xFF00A870); // 绿色 + bgColor = const Color(0xFFE6F7F1); + break; + case ReservationStatus.rejected: + text = "拒绝加氢"; + textColor = const Color(0xFFFF7D7D); // 红色 + bgColor = const Color(0xFFFFEEEE); + break; + case ReservationStatus.unadded: + text = '未加氢'; + textColor = const Color(0xFFFF7D7D); // 红色 + bgColor = const Color(0xFFFFEEEE); + break; + default: + text = "未知"; + textColor = Colors.grey; + bgColor = Colors.grey[100]!; + } + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: bgColor, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: textColor.withOpacity(0.3)), + ), + child: Text( + text, + style: TextStyle(color: textColor, fontSize: 11, fontWeight: FontWeight.bold), + ), + ); + } + + /// 右侧操作按钮(拒绝/确认) + Widget _buildActionButtons(ReservationModel item) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + // 拒绝按钮(空心) + GestureDetector( + onTap: () => controller.rejectReservation(item.id), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border.all(color: const Color(0xFFFF7D7D)), + ), + child: const Text( + "拒绝", + style: TextStyle( + color: Color(0xFFFF7D7D), + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + const SizedBox(width: 8), + // 确认按钮(实心深绿) + GestureDetector( + onTap: () => controller.confirmReservation(item.id), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + decoration: BoxDecoration( + color: const Color(0xFF006D35), + borderRadius: BorderRadius.circular(10), + ), + child: const Text( + "确认", + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ); + } + /// 构建状态标签 Widget _buildStatusChip(ReservationStatus status) { String text; @@ -555,12 +716,11 @@ class SitePage extends GetView { } /// 构建信息详情行 - Widget _buildDetailRow( - IconData icon, - String label, - String value, { - Color valueColor = Colors.black87, - }) { + Widget _buildDetailRow(IconData icon, + String label, + String value, { + Color valueColor = Colors.black87, + }) { return Row( children: [ Icon(icon, color: Colors.grey, size: 20),