diff --git a/ln_jq_app/assets/images/ic_car@2x.png b/ln_jq_app/assets/images/ic_car@2x.png new file mode 100644 index 0000000..986316b Binary files /dev/null and b/ln_jq_app/assets/images/ic_car@2x.png differ diff --git a/ln_jq_app/assets/images/ic_car_select@2x.png b/ln_jq_app/assets/images/ic_car_select@2x.png new file mode 100644 index 0000000..c22b9d2 Binary files /dev/null and b/ln_jq_app/assets/images/ic_car_select@2x.png differ diff --git a/ln_jq_app/assets/images/ic_h2@2x.png b/ln_jq_app/assets/images/ic_h2@2x.png new file mode 100644 index 0000000..0fac22d Binary files /dev/null and b/ln_jq_app/assets/images/ic_h2@2x.png differ diff --git a/ln_jq_app/assets/images/ic_h2_select@2x.png b/ln_jq_app/assets/images/ic_h2_select@2x.png new file mode 100644 index 0000000..4b1a721 Binary files /dev/null and b/ln_jq_app/assets/images/ic_h2_select@2x.png differ diff --git a/ln_jq_app/assets/images/ic_mall@2x.png b/ln_jq_app/assets/images/ic_mall@2x.png new file mode 100644 index 0000000..ea32836 Binary files /dev/null and b/ln_jq_app/assets/images/ic_mall@2x.png differ diff --git a/ln_jq_app/assets/images/ic_mall_select@2x.png b/ln_jq_app/assets/images/ic_mall_select@2x.png new file mode 100644 index 0000000..bb83031 Binary files /dev/null and b/ln_jq_app/assets/images/ic_mall_select@2x.png differ diff --git a/ln_jq_app/assets/images/ic_map@2x.png b/ln_jq_app/assets/images/ic_map@2x.png new file mode 100644 index 0000000..de99391 Binary files /dev/null and b/ln_jq_app/assets/images/ic_map@2x.png differ diff --git a/ln_jq_app/assets/images/ic_map_select@2x.png b/ln_jq_app/assets/images/ic_map_select@2x.png new file mode 100644 index 0000000..bd7a2ee Binary files /dev/null and b/ln_jq_app/assets/images/ic_map_select@2x.png differ diff --git a/ln_jq_app/assets/images/ic_user@2x.png b/ln_jq_app/assets/images/ic_user@2x.png new file mode 100644 index 0000000..ee5a716 Binary files /dev/null and b/ln_jq_app/assets/images/ic_user@2x.png differ diff --git a/ln_jq_app/assets/images/ic_user_select@2x.png b/ln_jq_app/assets/images/ic_user_select@2x.png new file mode 100644 index 0000000..fcfc538 Binary files /dev/null and b/ln_jq_app/assets/images/ic_user_select@2x.png differ diff --git a/ln_jq_app/lib/pages/c_page/base_widgets/view.dart b/ln_jq_app/lib/pages/c_page/base_widgets/view.dart index 81d539a..55a3fcb 100644 --- a/ln_jq_app/lib/pages/c_page/base_widgets/view.dart +++ b/ln_jq_app/lib/pages/c_page/base_widgets/view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:getx_scaffold/common/index.dart'; +import 'package:get/get.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; +import 'package:ln_jq_app/common/login_util.dart'; import 'package:ln_jq_app/pages/c_page/car_info/view.dart'; import 'package:ln_jq_app/pages/c_page/map/view.dart'; import 'package:ln_jq_app/pages/c_page/mine/view.dart'; @@ -9,9 +10,10 @@ import 'package:ln_jq_app/pages/c_page/reservation/view.dart'; import 'index.dart'; class BaseWidgetsPage extends GetView { - BaseWidgetsPage({super.key}); + BaseWidgetsPage({super.key}); final PageController _pageController = PageController(); + // 主视图 Widget _buildView() { return PageView( @@ -20,54 +22,68 @@ class BaseWidgetsPage extends GetView { onPageChanged: (index) { jumpTabAndPage(index); }, - children: _buildPages(), // 页面的列表 + children: _buildPages(), ); } void jumpTabAndPage(int index) { - controller.pageIndex = index; // 更新页面索引 - controller.updateUi(); // 更新 UI + controller.pageIndex = index; + controller.updateUi(); _pageController.jumpToPage(controller.pageIndex); } - // 对应的页面 + List _buildPages() { - return [ - ReservationPage(), - MapPage(), - CarInfoPage(), - MinePage(), - ]; + return [ReservationPage(), MapPage(), CarInfoPage(), MinePage()]; } - //导航栏 + // 自定义导航栏 (悬浮胶囊样式) Widget _buildNavigationBar() { - return NavigationX( - currentIndex: controller.pageIndex, // 当前选中的tab索引 - onTap: (index) { - jumpTabAndPage(index); - }, // 切换tab事件 - items: [ - NavigationItemModel( - label: '加氢预约', - icon: AntdIcon.orderedlist, - selectedIcon: AntdIcon.calendar_fill, + return SafeArea( + child: Container( + height: 50.h, + margin: const EdgeInsets.fromLTRB(24, 0, 24, 10), // 悬浮边距 + decoration: BoxDecoration( + color: Color.fromRGBO(240, 244, 247, 1), // 浅灰色背景 + borderRadius: BorderRadius.circular(30), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 10, + offset: const Offset(0, 5), + ), + ], ), - NavigationItemModel( - label: '地图', - icon: AntdIcon.location, - selectedIcon: AntdIcon.location_fill, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildNavItem(0, "ic_h2_select@2x", "ic_h2@2x"), + _buildNavItem(1, "ic_map_select@2x", "ic_map@2x"), + _buildNavItem(2, "ic_car_select@2x", "ic_car@2x"), + _buildNavItem(3, "ic_user_select@2x", "ic_user@2x"), + ], ), - NavigationItemModel( - label: '车辆信息', - icon: AntdIcon.car, - selectedIcon: AntdIcon.car_fill, + ), + ); + } + + // 构建单个导航项 + Widget _buildNavItem(int index, String icon, String selectedIcon) { + bool isSelected = controller.pageIndex == index; + return GestureDetector( + onTap: () => jumpTabAndPage(index), + behavior: HitTestBehavior.opaque, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + decoration: BoxDecoration( + color: isSelected ? const Color(0xFF006633) : Colors.transparent, // 选中时的深绿色背景 + borderRadius: BorderRadius.circular(20), ), - NavigationItemModel( - label: '我的', - icon: AntdIcon.user, - selectedIcon: AntdIcon.user, - ), - ], + child: SizedBox( + height: 24, + width: 24, + child: LoginUtil.getAssImg(isSelected ? selectedIcon : icon),), + ), ); } @@ -78,10 +94,10 @@ class BaseWidgetsPage extends GetView { id: 'baseWidgets', builder: (_) { return Scaffold( - extendBody: false, + extendBody: true, // 重要:让 body 延伸到导航栏后面 resizeToAvoidBottomInset: false, bottomNavigationBar: _buildNavigationBar(), - body: SafeArea(child: _buildView()), + body: _buildView(), // 移除 SafeArea 以获得更好的全屏沉浸感 ); }, ); diff --git a/ln_jq_app/lib/pages/c_page/car_info/view.dart b/ln_jq_app/lib/pages/c_page/car_info/view.dart index d0ca30f..ccc0bd6 100644 --- a/ln_jq_app/lib/pages/c_page/car_info/view.dart +++ b/ln_jq_app/lib/pages/c_page/car_info/view.dart @@ -26,7 +26,7 @@ class CarInfoPage extends GetView { children: [ _buildUserInfoCard(), Padding( - padding: EdgeInsets.only(left: 20.w,right: 20.w), + padding: EdgeInsets.only(left: 20.w, right: 20.w), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -35,6 +35,7 @@ class CarInfoPage extends GetView { _buildCertificatesCard(context), const SizedBox(height: 12), _buildSafetyReminderCard(), + SizedBox(height: 95.h), ], ), ), @@ -60,7 +61,7 @@ class CarInfoPage extends GetView { child: Column( children: [ Padding( - padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 16, top: 40), + padding: EdgeInsets.only(left: 20.w, right: 20.w, bottom: 16, top: 50), child: Row( children: [ Stack( @@ -344,7 +345,7 @@ class CarInfoPage extends GetView { ), const SizedBox(height: 9), SizedBox( - height: 343.h, // 给定一个高度,或者使用别的方式布局 + height: 333.h, // 给定一个高度,或者使用别的方式布局 child: TabBarView( children: [ _buildCertificateContent('行驶证', controller.drivingAttachments), @@ -362,66 +363,55 @@ class CarInfoPage extends GetView { /// 构建单个证件的展示内容 Widget _buildCertificateContent(String title, RxList attachments) { return Obx(() { - if (attachments.isEmpty) { - return const Center(child: Text('暂无相关证件信息')); - } return Card( elevation: 0, color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildCertDetailItem('所有人', '上海羚牛氢运物联网科技有限公司', isFull: true), - _buildCertDetailItem('车辆识别代号', controller.vin), - ], - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _buildCertDetailItem( - '有效期至', - '2028-08-14', - valueColor: const Color(0xFF52C41A), - ), - _buildCertDetailItem('使用性质', '货运'), - ], - ), - const SizedBox(height: 20), - // 附件预览部分 - Expanded( - child: ListView.builder( - scrollDirection: Axis.vertical, - itemCount: attachments.length, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - final url = attachments[index]; - return GestureDetector( + padding: EdgeInsets.all(16.0), + child: attachments.isEmpty + ? const Center(child: Text('暂无相关证件信息')) + : Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildCertDetailItem('所有人', '上海羚牛氢运物联网科技有限公司', isFull: true), + _buildCertDetailItem('车辆识别代号', controller.vin), + ], + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildCertDetailItem( + '有效期至', + '2028-08-14', + valueColor: const Color(0xFF52C41A), + ), + _buildCertDetailItem('使用性质', '货运'), + ], + ), + const SizedBox(height: 16), + // 附件预览部分 + GestureDetector( onTap: () { - controller.openAttachment(url); + controller.navigateToCertificateViewer(title, attachments); }, child: Container( height: 184.h, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), border: Border.all(color: Color.fromRGBO(226, 232, 240, 1)), - color: Color.fromRGBO(248, 250, 252, 1) + color: Color.fromRGBO(248, 250, 252, 1), ), - child: Center(child: _buildAttachmentPreview(url)), + child: Center(child: _buildAttachmentPreview(attachments[0])), ), - ); - }, + ), + ], ), - ), - ], - ), ), ); }); 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 35965c8..3e7ea1e 100644 --- a/ln_jq_app/lib/pages/c_page/mine/view.dart +++ b/ln_jq_app/lib/pages/c_page/mine/view.dart @@ -38,7 +38,7 @@ class MinePage extends GetView { _buildSafetyReminderCard(), SizedBox(height: 24.h), _buildLogoutButton(), - SizedBox(height: 24.h), + SizedBox(height: 95.h), ], ), ), diff --git a/ln_jq_app/lib/pages/c_page/reservation/view.dart b/ln_jq_app/lib/pages/c_page/reservation/view.dart index 53f6f8e..e6c8da7 100644 --- a/ln_jq_app/lib/pages/c_page/reservation/view.dart +++ b/ln_jq_app/lib/pages/c_page/reservation/view.dart @@ -37,6 +37,7 @@ class ReservationPage extends GetView { _buildReservationFormCard(context), const SizedBox(height: 5), _buildTipsCard(), + SizedBox(height: 95.h), ], ), ), @@ -474,7 +475,7 @@ class ReservationPage extends GetView { ), ), Obx( - () => DropdownButtonHideUnderline( + () => DropdownButtonHideUnderline( child: DropdownButton2( isExpanded: true, hint: const Text( @@ -485,15 +486,15 @@ class ReservationPage extends GetView { items: controller.stationOptions .map( (station) => DropdownMenuItem( - value: station.hydrogenId, // value 是站点的唯一ID - enabled: station.isSelect == 1, - child: _buildDropdownItem(station), // child 是自定义的 Widget - ), - ) + value: station.hydrogenId, // value 是站点的唯一ID + enabled: station.isSelect == 1, + child: _buildDropdownItem(station), // child 是自定义的 Widget + ), + ) .toList(), value: - // 当前的站点 处理默认 - controller.selectedStationId.value ?? + // 当前的站点 处理默认 + controller.selectedStationId.value ?? (controller.stationOptions.isNotEmpty ? controller.stationOptions.first.hydrogenId : null), @@ -506,15 +507,15 @@ class ReservationPage extends GetView { customButton: Obx(() { // 优先从已选中的 ID 查找 var selectedStation = controller.stationOptions.firstWhereOrNull( - (s) => s.hydrogenId == controller.selectedStationId.value, + (s) => s.hydrogenId == controller.selectedStationId.value, ); // 如果找不到已选中的(比如 ID 为空或列表里没有),并且列表不为空,则取第一个作为默认 final stationToShow = selectedStation ?? - (controller.stationOptions.isNotEmpty - ? controller.stationOptions.first - : null); + (controller.stationOptions.isNotEmpty + ? controller.stationOptions.first + : null); // 如果有要显示的站点,就构建按钮 if (stationToShow != null) {