From 3d9d3e90428e158cd4eac8ccf572371e70ae6f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Thu, 23 Oct 2025 10:43:14 +0800 Subject: [PATCH] refactor : app_bar_add,app_bar_upload --- lib/app/core/routes/app_pages.dart | 7 + lib/app/core/routes/app_routes.dart | 1 + lib/app/core/widgets/app_bar_add.dart | 44 +++++ lib/app/core/widgets/upload_app_bar.dart | 67 ++++++++ .../bindings/enterprise_upload_binding.dart | 8 + .../pages/enterprise_form_page.dart | 2 +- .../pages/enterprise_info_page.dart | 2 +- .../pages/enterprise_list_page.dart | 50 +----- .../pages/enterprise_upload_page.dart | 20 +++ .../{ => pages}/widgets/enterprise_card.dart | 0 .../widgets/enterprise_form_view.dart | 0 .../controllers/navigation_controller.dart | 11 +- .../presentation/views/problem_page.dart | 155 +++++++----------- .../views/problem_upload_page.dart | 10 +- .../{ => widgets}/problem_list_page.dart | 0 15 files changed, 238 insertions(+), 139 deletions(-) create mode 100644 lib/app/core/widgets/app_bar_add.dart create mode 100644 lib/app/core/widgets/upload_app_bar.dart create mode 100644 lib/app/features/enterprise/presentation/bindings/enterprise_upload_binding.dart create mode 100644 lib/app/features/enterprise/presentation/pages/enterprise_upload_page.dart rename lib/app/features/enterprise/presentation/{ => pages}/widgets/enterprise_card.dart (100%) rename lib/app/features/enterprise/presentation/{ => pages}/widgets/enterprise_form_view.dart (100%) rename lib/app/features/problem/presentation/views/{ => widgets}/problem_list_page.dart (100%) diff --git a/lib/app/core/routes/app_pages.dart b/lib/app/core/routes/app_pages.dart index 4289809..49e15c6 100644 --- a/lib/app/core/routes/app_pages.dart +++ b/lib/app/core/routes/app_pages.dart @@ -1,7 +1,9 @@ import 'package:get/get.dart'; import 'package:problem_check_system/app/features/enterprise/presentation/bindings/enterprise_form_binding.dart'; import 'package:problem_check_system/app/features/enterprise/presentation/bindings/enterprise_info_binding.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/bindings/enterprise_upload_binding.dart'; import 'package:problem_check_system/app/features/enterprise/presentation/pages/enterprise_form_page.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/pages/enterprise_upload_page.dart'; import 'package:problem_check_system/app/features/navigation/presentation/bindings/navigation_binding.dart'; import 'package:problem_check_system/app/features/navigation/presentation/pages/navigation_page.dart'; import 'package:problem_check_system/app/features/home/bindings/home_binding.dart'; @@ -60,5 +62,10 @@ abstract class AppPages { page: () => const EnterpriseFormPage(), binding: EnterpriseFormBinding(), ), + GetPage( + name: AppRoutes.enterpriseUpload, + page: () => const EnterpriseUploadPage(), + binding: EnterpriseUploadBinding(), + ), ]; } diff --git a/lib/app/core/routes/app_routes.dart b/lib/app/core/routes/app_routes.dart index 3679cf4..49bef4b 100644 --- a/lib/app/core/routes/app_routes.dart +++ b/lib/app/core/routes/app_routes.dart @@ -17,5 +17,6 @@ abstract class AppRoutes { static const enterpriseInfo = '/enterpriseInfo'; static const enterpriseList = '/enterpriseList'; static const enterpriseForm = '/enterpriseForm'; + static const enterpriseUpload = '/enterpriseUpload'; // #endregion } diff --git a/lib/app/core/widgets/app_bar_add.dart b/lib/app/core/widgets/app_bar_add.dart new file mode 100644 index 0000000..5abc4d9 --- /dev/null +++ b/lib/app/core/widgets/app_bar_add.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class AppBarAdd extends StatelessWidget implements PreferredSizeWidget { + const AppBarAdd({super.key, required this.titleName, this.onAddPressed}); + final String titleName; + final VoidCallback? onAddPressed; + + @override + Widget build(BuildContext context) { + return AppBar( + title: Text( + titleName, + style: TextStyle( + fontWeight: FontWeight.bold, + fontFamily: 'MyFont', + fontSize: 18.sp, + color: Colors.white, + ), + ), + backgroundColor: Colors.transparent, + flexibleSpace: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + ), + elevation: 0, + centerTitle: true, + actions: [ + IconButton( + icon: Icon(Icons.add, color: Colors.white), // 使用 .sp + onPressed: onAddPressed, + ), + ], + ); + } + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} diff --git a/lib/app/core/widgets/upload_app_bar.dart b/lib/app/core/widgets/upload_app_bar.dart new file mode 100644 index 0000000..66a18d0 --- /dev/null +++ b/lib/app/core/widgets/upload_app_bar.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +class UploadAppBar extends StatelessWidget implements PreferredSizeWidget { + const UploadAppBar({ + super.key, + required this.selectedAll, + required this.selectedCount, + required this.buttonVisible, + this.onButtonPressed, + }); + final int selectedCount; + final bool selectedAll; + final bool buttonVisible; + final VoidCallback? onButtonPressed; + + @override + Widget build(BuildContext context) { + return AppBar( + title: Text( + "已选择$selectedCount项", + style: TextStyle( + fontFamily: 'MyFont', + fontSize: 17.5.sp, + color: Colors.white, + ), + ), + centerTitle: true, + backgroundColor: Colors.transparent, + flexibleSpace: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + ), + elevation: 0, + systemOverlayStyle: SystemUiOverlayStyle.dark, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: Colors.white, size: 20), + onPressed: () { + Get.back(); + }, + ), + actions: [ + TextButton( + onPressed: buttonVisible ? onButtonPressed : null, + child: Text( + selectedAll ? "全选" : "取消全选", + style: TextStyle( + color: buttonVisible ? Colors.white : Colors.grey[300], + fontSize: 15.sp, + fontFamily: "MyFont", + ), + ), + ), + ], + ); + } + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} diff --git a/lib/app/features/enterprise/presentation/bindings/enterprise_upload_binding.dart b/lib/app/features/enterprise/presentation/bindings/enterprise_upload_binding.dart new file mode 100644 index 0000000..0064f36 --- /dev/null +++ b/lib/app/features/enterprise/presentation/bindings/enterprise_upload_binding.dart @@ -0,0 +1,8 @@ +import 'package:get/get.dart'; + +class EnterpriseUploadBinding extends Bindings { + @override + void dependencies() { + // TODO: implement dependencies + } +} diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart index 36ebe70..95a18bd 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_form_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:problem_check_system/app/features/enterprise/presentation/controllers/enterprise_form_controller.dart'; -import 'package:problem_check_system/app/features/enterprise/presentation/widgets/enterprise_form_view.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/pages/widgets/enterprise_form_view.dart'; // ------------------- 页面视图 (View) ------------------- // 使用 GetView 可以方便地访问控制器 diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_info_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_info_page.dart index 1014e41..628121b 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_info_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_info_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:problem_check_system/app/features/enterprise/presentation/widgets/enterprise_form_view.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/pages/widgets/enterprise_form_view.dart'; // 支付宝消息页面 class EnterpriseInfoPage extends StatelessWidget { diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart index a12bc9a..58107ba 100644 --- a/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart +++ b/lib/app/features/enterprise/presentation/pages/enterprise_list_page.dart @@ -3,7 +3,8 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:problem_check_system/app/core/extensions/datetime_extension.dart'; import 'package:problem_check_system/app/core/models/company_enum.dart'; -import 'package:problem_check_system/app/features/enterprise/presentation/widgets/enterprise_card.dart'; +import 'package:problem_check_system/app/core/widgets/app_bar_add.dart'; +import 'package:problem_check_system/app/features/enterprise/presentation/pages/widgets/enterprise_card.dart'; import '../controllers/enterprise_list_controller.dart'; class EnterpriseListPage extends GetView { @@ -12,42 +13,9 @@ class EnterpriseListPage extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text( - '企业列表', - style: TextStyle( - fontWeight: FontWeight.bold, - fontFamily: 'MyFont', - fontSize: 18.sp, - color: Colors.white, - ), - ), - backgroundColor: Colors.transparent, - flexibleSpace: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], - begin: Alignment.centerLeft, - end: Alignment.centerRight, - ), - ), - ), - elevation: 0, - centerTitle: true, - actions: [ - IconButton( - icon: Icon(Icons.add, color: Colors.white), // 使用 .sp - onPressed: () { - controller.navigateToAddForm(); - }, - ), - // IconButton( - // icon: Icon(Icons.upload, color: Colors.pink[300]), // 使用 .sp - // onPressed: () { - // controller.navigateToUploadPage(); - // }, - // ), - ], + appBar: AppBarAdd( + titleName: '企业列表', + onAddPressed: () => controller.navigateToAddForm(), ), body: Stack( children: [ @@ -71,7 +39,7 @@ class EnterpriseListPage extends GetView { initiallyExpanded: false, // 默认收起 children: [ Padding( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 1.h), + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 4.h), child: Column( children: [ // 1. 企业名称输入框 @@ -170,8 +138,8 @@ class EnterpriseListPage extends GetView { final pickedDate = await showDatePicker( context: Get.context!, initialDate: date.value ?? DateTime.now(), - firstDate: DateTime(2020), - lastDate: DateTime(2101), + firstDate: DateTime(2025), + lastDate: DateTime(2125), ); if (pickedDate != null) { date.value = pickedDate; @@ -186,7 +154,7 @@ class EnterpriseListPage extends GetView { ), child: Obx( () => Text( - date.value == null ? '请选择日期' : date.value!.toDateTimeString(), + date.value == null ? '请选择日期' : date.value!.toDateString(), style: TextStyle( color: date.value == null ? Colors.grey[600] : Colors.black87, ), diff --git a/lib/app/features/enterprise/presentation/pages/enterprise_upload_page.dart b/lib/app/features/enterprise/presentation/pages/enterprise_upload_page.dart new file mode 100644 index 0000000..28ce425 --- /dev/null +++ b/lib/app/features/enterprise/presentation/pages/enterprise_upload_page.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:problem_check_system/app/core/widgets/upload_app_bar.dart'; + +class EnterpriseUploadPage extends StatelessWidget { + const EnterpriseUploadPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: UploadAppBar( + selectedCount: 10, + selectedAll: true, + buttonVisible: false, + onButtonPressed: () { + print("object"); + }, + ), + ); + } +} diff --git a/lib/app/features/enterprise/presentation/widgets/enterprise_card.dart b/lib/app/features/enterprise/presentation/pages/widgets/enterprise_card.dart similarity index 100% rename from lib/app/features/enterprise/presentation/widgets/enterprise_card.dart rename to lib/app/features/enterprise/presentation/pages/widgets/enterprise_card.dart diff --git a/lib/app/features/enterprise/presentation/widgets/enterprise_form_view.dart b/lib/app/features/enterprise/presentation/pages/widgets/enterprise_form_view.dart similarity index 100% rename from lib/app/features/enterprise/presentation/widgets/enterprise_form_view.dart rename to lib/app/features/enterprise/presentation/pages/widgets/enterprise_form_view.dart diff --git a/lib/app/features/navigation/presentation/controllers/navigation_controller.dart b/lib/app/features/navigation/presentation/controllers/navigation_controller.dart index 92352e7..d036bb1 100644 --- a/lib/app/features/navigation/presentation/controllers/navigation_controller.dart +++ b/lib/app/features/navigation/presentation/controllers/navigation_controller.dart @@ -31,6 +31,13 @@ class NavigationController extends GetxController { get currentPage => pages[selectedIndex.value]; + @override + void onInit() { + super.onInit(); + updateFabUploadPosition(Offset.infinite); + snapToEdge(); + } + void changePageIndex(int index) { selectedIndex.value = index; } @@ -85,11 +92,11 @@ class NavigationController extends GetxController { case 1: // 企业列表页面 Get.log("当前在企业页面,准备跳转到企业数据上传页..."); // 使用命名路由进行跳转,这是最佳实践 - // Get.toNamed(AppRoutes.ENTERPRISE_UPLOAD); + Get.toNamed(AppRoutes.enterpriseUpload); break; case 2: // 问题列表页面 Get.log("当前在问题页面,准备跳转到问题上传页..."); - // Get.toNamed(AppRoutes.PROBLEM_UPLOAD); + Get.toNamed(AppRoutes.problemUpload); break; default: // 在其他页面(如首页、我的)点击时,可以不响应或给一个提示 diff --git a/lib/app/features/problem/presentation/views/problem_page.dart b/lib/app/features/problem/presentation/views/problem_page.dart index 53510c2..c2a43f5 100644 --- a/lib/app/features/problem/presentation/views/problem_page.dart +++ b/lib/app/features/problem/presentation/views/problem_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:problem_check_system/app/core/widgets/app_bar_add.dart'; import 'package:problem_check_system/app/features/problem/presentation/controllers/problem_controller.dart'; -import 'package:problem_check_system/app/features/problem/presentation/views/problem_list_page.dart'; // 导入修正后的 ProblemListPage +import 'package:problem_check_system/app/features/problem/presentation/views/widgets/problem_list_page.dart'; import 'package:problem_check_system/app/features/problem/presentation/views/widgets/current_filter_bar.dart'; -import 'package:problem_check_system/app/features/problem/presentation/views/widgets/history_filter_bar.dart'; -import 'package:problem_check_system/app/features/problem/presentation/views/widgets/problem_card.dart'; // 导入自定义下拉菜单 +import 'package:problem_check_system/app/features/problem/presentation/views/widgets/problem_card.dart'; class ProblemPage extends GetView { const ProblemPage({super.key}); @@ -13,38 +13,9 @@ class ProblemPage extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text( - '问题列表', - style: TextStyle( - fontWeight: FontWeight.bold, - fontFamily: 'MyFont', - fontSize: 18.sp, - color: Colors.white, - ), - ), - backgroundColor: Colors.transparent, - flexibleSpace: Container( - decoration: const BoxDecoration( - gradient: LinearGradient( - colors: [Color(0xFF418CFC), Color(0xFF3DBFFC)], - begin: Alignment.centerLeft, - end: Alignment.centerRight, - ), - ), - ), - elevation: 0, - centerTitle: true, - actions: [ - IconButton( - icon: Icon(Icons.add, color: Colors.white), // 使用 .sp - onPressed: () {}, - ), - IconButton( - icon: Icon(Icons.upload, color: Colors.pink[300]), // 使用 .sp - onPressed: () {}, - ), - ], + appBar: AppBarAdd( + titleName: '问题列表', + onAddPressed: () => controller.toProblemFormPageAndRefresh(), ), body: Column( children: [ @@ -59,65 +30,65 @@ class ProblemPage extends GetView { ], ), - floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + // floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, // 使用 Stack 统一管理所有浮动按钮 - floatingActionButton: Stack( - children: [ - // 固定位置的 "添加" 按钮 - // 使用 Align 和 Positioned - Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: EdgeInsets.only(bottom: 24.h), // 底部间距 - child: FloatingActionButton( - heroTag: "btn_add", - onPressed: () { - controller.toProblemFormPageAndRefresh(); - }, - shape: const CircleBorder(), - backgroundColor: Colors.blue[300], - foregroundColor: Colors.white, - child: const Icon(Icons.add), - ), - ), - ), + // floatingActionButton: Stack( + // children: [ + // // 固定位置的 "添加" 按钮 + // // 使用 Align 和 Positioned + // Align( + // alignment: Alignment.bottomCenter, + // child: Padding( + // padding: EdgeInsets.only(bottom: 24.h), // 底部间距 + // child: FloatingActionButton( + // heroTag: "btn_add", + // onPressed: () { + // controller.toProblemFormPageAndRefresh(); + // }, + // shape: const CircleBorder(), + // backgroundColor: Colors.blue[300], + // foregroundColor: Colors.white, + // child: const Icon(Icons.add), + // ), + // ), + // ), - // 可拖动的 "上传" 按钮 - Obx(() { - final isOnline = controller.isOnline.value; - return Positioned( - // 使用正确的坐标,left/right 对应 dx,top/bottom 对应 dy - left: controller.fabUploadPosition.value.dx, - top: controller.fabUploadPosition.value.dy, - child: GestureDetector( - onPanUpdate: (details) { - // 调用控制器中的方法来更新位置 - controller.updateFabUploadPosition(details.delta); - }, - onPanEnd: (details) { - // 拖动结束后调用吸附方法 - controller.snapToEdge(); - }, - child: FloatingActionButton( - heroTag: "btn_upload", - onPressed: isOnline - ? () => controller.showUploadPage() - : null, - foregroundColor: Colors.white, - backgroundColor: isOnline - ? Colors.red[300] - : Colors.grey[400], - child: Icon( - isOnline - ? Icons.file_upload_outlined - : Icons.cloud_off_outlined, - ), - ), - ), - ); - }), - ], - ), + // // 可拖动的 "上传" 按钮 + // Obx(() { + // final isOnline = controller.isOnline.value; + // return Positioned( + // // 使用正确的坐标,left/right 对应 dx,top/bottom 对应 dy + // left: controller.fabUploadPosition.value.dx, + // top: controller.fabUploadPosition.value.dy, + // child: GestureDetector( + // onPanUpdate: (details) { + // // 调用控制器中的方法来更新位置 + // controller.updateFabUploadPosition(details.delta); + // }, + // onPanEnd: (details) { + // // 拖动结束后调用吸附方法 + // controller.snapToEdge(); + // }, + // child: FloatingActionButton( + // heroTag: "btn_upload", + // onPressed: isOnline + // ? () => controller.showUploadPage() + // : null, + // foregroundColor: Colors.white, + // backgroundColor: isOnline + // ? Colors.red[300] + // : Colors.grey[400], + // child: Icon( + // isOnline + // ? Icons.file_upload_outlined + // : Icons.cloud_off_outlined, + // ), + // ), + // ), + // ); + // }), + // ], + // ), ); } } diff --git a/lib/app/features/problem/presentation/views/problem_upload_page.dart b/lib/app/features/problem/presentation/views/problem_upload_page.dart index a77d54a..6c75991 100644 --- a/lib/app/features/problem/presentation/views/problem_upload_page.dart +++ b/lib/app/features/problem/presentation/views/problem_upload_page.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:problem_check_system/app/core/widgets/upload_app_bar.dart'; import 'package:problem_check_system/app/features/problem/presentation/controllers/problem_controller.dart'; -import 'package:problem_check_system/app/features/problem/presentation/views/problem_list_page.dart'; +import 'package:problem_check_system/app/features/problem/presentation/views/widgets/problem_list_page.dart'; import 'package:problem_check_system/app/features/problem/presentation/views/widgets/problem_card.dart'; class ProblemUploadPage extends GetView { @@ -11,7 +12,12 @@ class ProblemUploadPage extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: _buildAppBar(), + appBar: UploadAppBar( + selectedCount: controller.selectedCount, + selectedAll: controller.allSelected.value, + buttonVisible: controller.unUploadedProblems.isNotEmpty, + onButtonPressed: controller.selectAll, + ), body: _buildBody(), bottomNavigationBar: _buildBottomBar(), ); diff --git a/lib/app/features/problem/presentation/views/problem_list_page.dart b/lib/app/features/problem/presentation/views/widgets/problem_list_page.dart similarity index 100% rename from lib/app/features/problem/presentation/views/problem_list_page.dart rename to lib/app/features/problem/presentation/views/widgets/problem_list_page.dart