4 Commits 7b6936683b ... e2b1624b32

Author SHA1 Message Date
  liukai e2b1624b32 Merge remote-tracking branch 'origin/dev' into dev 4 days ago
  liukai 8653907739 设施的确认页面与详情页面 4 days ago
  liukai 9814a01fd4 完善两个日期选择的联动 4 days ago
  liukai 279da333f7 星期选择与日历选择的初步完成 4 days ago
44 changed files with 1737 additions and 866 deletions
  1. 63 110
      packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart
  2. 0 3
      packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.dart
  3. 1 1
      packages/cpt_auth/lib/modules/select_role/select_role_page.dart
  4. 151 199
      packages/cpt_auth/lib/modules/select_unit/select_unit_page.dart
  5. 0 4
      packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.dart
  6. 0 92
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_full_screen.dart
  7. 73 6
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart
  8. 0 90
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_small_screen.dart
  9. 3 1
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_view_model.dart
  10. 53 100
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_page.dart
  11. 0 4
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.dart
  12. 0 5
      packages/cpt_auth/lib/router/component/auth_component_service.dart
  13. 284 0
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_page.dart
  14. 3 0
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_state.dart
  15. 25 0
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.dart
  16. 27 0
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.g.dart
  17. 176 26
      packages/cpt_facility/lib/modules/booking/facility_booking_page.dart
  18. 34 2
      packages/cpt_facility/lib/modules/booking/facility_booking_state.dart
  19. 56 3
      packages/cpt_facility/lib/modules/booking/facility_booking_view_model.dart
  20. 1 1
      packages/cpt_facility/lib/modules/booking/facility_booking_view_model.g.dart
  21. 12 2
      packages/cpt_facility/lib/modules/detail/facility_detail_page.dart
  22. 3 4
      packages/cpt_facility/lib/modules/facility/history/facility_history_screen.dart
  23. 2 0
      packages/cpt_facility/lib/router/page/facility_page_router.dart
  24. 20 0
      packages/cpt_facility/lib/router/page/facility_page_router.gr.dart
  25. 1 1
      packages/cpt_property/lib/modules/property/vm/property_vm.g.dart
  26. BIN
      packages/cs_resources/assets/base_lib/calendar_left_icon.webp
  27. BIN
      packages/cs_resources/assets/base_lib/calendar_right_icon.webp
  28. 2 0
      packages/cs_resources/lib/generated/assets.dart
  29. 10 2
      packages/cs_resources/lib/generated/intl/messages_en.dart
  30. 8 2
      packages/cs_resources/lib/generated/intl/messages_zh_CN.dart
  31. 8 2
      packages/cs_resources/lib/generated/intl/messages_zh_HK.dart
  32. 40 0
      packages/cs_resources/lib/generated/l10n.dart
  33. 4 0
      packages/cs_resources/lib/l10n/intl_en.arb
  34. 4 0
      packages/cs_resources/lib/l10n/intl_zh_CN.arb
  35. 4 0
      packages/cs_resources/lib/l10n/intl_zh_HK.arb
  36. 0 2
      packages/cs_router/lib/componentRouter/auth_service.dart
  37. 1 0
      packages/cs_router/lib/path/router_path.dart
  38. 49 0
      packages/cs_widgets/lib/shatter/select_calendar/calendar_bottom_sheet.dart
  39. 336 0
      packages/cs_widgets/lib/shatter/select_calendar/full_calendar.dart
  40. 32 10
      packages/cs_widgets/lib/shatter/weekly_calendar/calendar_utils.dart
  41. 5 6
      packages/cs_widgets/lib/shatter/weekly_calendar/day_cell.dart
  42. 5 9
      packages/cs_widgets/lib/shatter/weekly_calendar/day_table_view.dart
  43. 203 151
      packages/cs_widgets/lib/shatter/weekly_calendar/week_page.dart
  44. 38 28
      packages/cs_widgets/lib/shatter/weekly_calendar/weekly_calendar.dart

+ 63 - 110
packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart

@@ -4,10 +4,8 @@ import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:auto_route/auto_route.dart';
-import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/ext/auto_router_extensions.dart';
-import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_button.dart';
@@ -32,121 +30,76 @@ class SelectEstatePage extends HookConsumerWidget {
     }
     }
   }
   }
 
 
-  // 为需要测量的控件创建 GlobalKey
-  final GlobalKey _appbarKey = GlobalKey();
-  final GlobalKey _topImageKey = GlobalKey();
-  final GlobalKey _titleKey = GlobalKey();
-  final GlobalKey _inputKey = GlobalKey();
-  final GlobalKey _descriptionKey = GlobalKey();
-  final GlobalKey _buttonKey = GlobalKey();
-
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.watch(selectEstateViewModelProvider.notifier);
     final viewModel = ref.watch(selectEstateViewModelProvider.notifier);
     final state = ref.watch(selectEstateViewModelProvider);
     final state = ref.watch(selectEstateViewModelProvider);
 
 
-    // 获取屏幕高度
-    final screenHeight = MediaQuery.of(context).size.height;
-    final statusBarHeight = MediaQuery.of(context).padding.top;
-    final navigationBarHeight = MediaQuery.of(context).padding.bottom;
-
-    useEffect(() {
-      double usedHeight = 0;
-      // 组件挂载时执行,获取控件高度
-      WidgetsBinding.instance.addPostFrameCallback((_) {
-        // 获取各个控件的高度
-        usedHeight += _appbarKey.currentContext?.size?.height ?? 0;
-        usedHeight += _topImageKey.currentContext?.size?.height ?? 0;
-        usedHeight += _titleKey.currentContext?.size?.height ?? 0;
-        usedHeight += _inputKey.currentContext?.size?.height ?? 0;
-        usedHeight += _descriptionKey.currentContext?.size?.height ?? 0;
-        usedHeight += _buttonKey.currentContext?.size?.height ?? 0;
-
-        // 计算剩余空间
-        double remainingSpace = screenHeight - statusBarHeight - navigationBarHeight - usedHeight - 38 - 28 - 20 - 19;
-
-        Log.d("计算剩余空间:$remainingSpace");
-
-        if (remainingSpace > 0) {
-          // 设置一个状态来存储剩余空间的高度
-          viewModel.setRemainingSpace(remainingSpace);
-        }
-      });
-      return () {
-        // 组件卸载时执行
-      };
-    }, []);
-
     return Scaffold(
     return Scaffold(
-      appBar: MyAppBar.appBar(context, S.current.yy_home_accounts, key: _appbarKey),
+      appBar: MyAppBar.appBar(context, S.current.yy_home_accounts),
       backgroundColor: context.appColors.backgroundDefault,
       backgroundColor: context.appColors.backgroundDefault,
-      body: SingleChildScrollView(
-        scrollDirection: Axis.vertical,
-        physics: const BouncingScrollPhysics(),
-        child: Container(
-          padding: const EdgeInsets.symmetric(horizontal: 38),
-          width: double.infinity,
-          child: Column(
-            mainAxisSize: MainAxisSize.max,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              //顶部图片
-              MyAssetImage(
-                key: _topImageKey,
-                Assets.authChooseEstateBuilding,
-                width: 267,
-                height: 158,
-              ).marginOnly(top: 28, bottom: 38),
-
-              MyTextView(
-                key: _titleKey,
-                S.current.estate_or_building_name,
-                fontSize: 23,
-                marginBottom: 20,
-                textAlign: TextAlign.center,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              //输入资产的名称
-              _buildInputLayout(
-                context,
-                state,
-                "estate",
-                key: _inputKey,
-                textInputAction: TextInputAction.done,
-                onSubmit: (formKey, value) {
-                  state.formData[formKey]!['focusNode'].unfocus();
-                },
-              ),
-
-              MyTextView(
-                key: _descriptionKey,
-                S.current.estate_name_desc,
-                fontSize: 15,
-                marginTop: 19,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              SizedBox(
-                height: state.remainingSpace, // 使用剩余空间的值
-              ),
-
-              MyButton(
-                key: _buttonKey,
-                onPressed: viewModel.submitEstate,
-                text: S.current.next,
-                textColor: Colors.white,
-                backgroundColor: context.appColors.btnBgDefault,
-                fontWeight: FontWeight.w500,
-                type: ClickType.throttle,
-                fontSize: 16,
-                minHeight: 50,
-                radius: 5,
-              ).marginOnly(top: 40, bottom: 30),
-            ],
-          ),
+      body: Container(
+        padding: const EdgeInsets.symmetric(horizontal: 38),
+        width: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    //顶部图片
+                    const MyAssetImage(
+                      Assets.authChooseEstateBuilding,
+                      width: 267,
+                      height: 158,
+                    ).marginOnly(top: 28, bottom: 38),
+
+                    MyTextView(
+                      S.current.estate_or_building_name,
+                      fontSize: 23,
+                      marginBottom: 20,
+                      textAlign: TextAlign.center,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    //输入资产的名称
+                    _buildInputLayout(
+                      context,
+                      state,
+                      "estate",
+                      textInputAction: TextInputAction.done,
+                      onSubmit: (formKey, value) {
+                        state.formData[formKey]!['focusNode'].unfocus();
+                      },
+                    ),
+
+                    MyTextView(
+                      S.current.estate_name_desc,
+                      fontSize: 15,
+                      marginTop: 19,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                )).expanded(),
+
+            MyButton(
+              onPressed: viewModel.submitEstate,
+              text: S.current.next,
+              textColor: Colors.white,
+              backgroundColor: context.appColors.btnBgDefault,
+              fontWeight: FontWeight.w500,
+              type: ClickType.throttle,
+              fontSize: 16,
+              minHeight: 50,
+              radius: 5,
+            ).marginOnly(top: 50, bottom: 50),
+          ],
         ),
         ),
       ),
       ),
     );
     );

+ 0 - 3
packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.dart

@@ -18,7 +18,4 @@ class SelectEstateViewModel extends _$SelectEstateViewModel {
     SelectUnitPage.startInstance();
     SelectUnitPage.startInstance();
   }
   }
 
 
-  void setRemainingSpace(double remainingSpace) {
-    state = state.copyWith(remainingSpace: remainingSpace);
-  }
 }
 }

+ 1 - 1
packages/cpt_auth/lib/modules/select_role/select_role_page.dart

@@ -106,7 +106,7 @@ class SelectRolePage extends HookConsumerWidget {
               fontSize: 16,
               fontSize: 16,
               minHeight: 50,
               minHeight: 50,
               radius: 5,
               radius: 5,
-            ).marginOnly(top: 30, bottom: 30, left: 18, right: 18),
+            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
           ],
           ],
         ),
         ),
       ),
       ),

+ 151 - 199
packages/cpt_auth/lib/modules/select_unit/select_unit_page.dart

@@ -32,212 +32,164 @@ class SelectUnitPage extends HookConsumerWidget {
     }
     }
   }
   }
 
 
-  // 为需要测量的控件创建 GlobalKey
-  final GlobalKey _appbarKey = GlobalKey();
-  final GlobalKey _topImageKey = GlobalKey();
-  final GlobalKey _inputKey = GlobalKey();
-  final GlobalKey _description1Key = GlobalKey();
-  final GlobalKey _description2Key = GlobalKey();
-  final GlobalKey _description3Key = GlobalKey();
-  final GlobalKey _buttonKey = GlobalKey();
-
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.watch(selectUnitViewModelProvider.notifier);
     final viewModel = ref.watch(selectUnitViewModelProvider.notifier);
     final state = ref.watch(selectUnitViewModelProvider);
     final state = ref.watch(selectUnitViewModelProvider);
 
 
-    // 获取屏幕高度
-    final screenHeight = MediaQuery.of(context).size.height;
-    final statusBarHeight = MediaQuery.of(context).padding.top;
-    final navigationBarHeight = MediaQuery.of(context).padding.bottom;
-
-    useEffect(() {
-      double usedHeight = 0;
-      // 组件挂载时执行,获取控件高度
-      WidgetsBinding.instance.addPostFrameCallback((_) {
-        // 获取各个控件的高度
-        usedHeight += _appbarKey.currentContext?.size?.height ?? 0;
-        usedHeight += _topImageKey.currentContext?.size?.height ?? 0;
-        usedHeight += _inputKey.currentContext?.size?.height ?? 0;
-        usedHeight += _description1Key.currentContext?.size?.height ?? 0;
-        usedHeight += _description2Key.currentContext?.size?.height ?? 0;
-        usedHeight += _description3Key.currentContext?.size?.height ?? 0;
-        usedHeight += _buttonKey.currentContext?.size?.height ?? 0;
-
-        // 计算剩余空间
-        double remainingSpace = screenHeight - statusBarHeight - navigationBarHeight - usedHeight - 28 - 18 - 25 - 20 - 20;
-
-        Log.d("计算剩余空间:$remainingSpace");
-
-        if (remainingSpace > 0) {
-          // 设置一个状态来存储剩余空间的高度
-          viewModel.setRemainingSpace(remainingSpace);
-        }
-      });
-      return () {
-        // 组件卸载时执行
-      };
-    }, []);
-
     return Scaffold(
     return Scaffold(
-      appBar: MyAppBar.appBar(context, S.current.yy_home_accounts, key: _appbarKey),
+      appBar: MyAppBar.appBar(context, S.current.yy_home_accounts),
       backgroundColor: context.appColors.backgroundDefault,
       backgroundColor: context.appColors.backgroundDefault,
-      body: SingleChildScrollView(
-        scrollDirection: Axis.vertical,
-        physics: const BouncingScrollPhysics(),
-        child: Container(
-          padding: const EdgeInsets.symmetric(horizontal: 20),
-          width: double.infinity,
-          child: Column(
-            mainAxisSize: MainAxisSize.max,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              //顶部图片
-              MyAssetImage(
-                key: _topImageKey,
-                Assets.authSignUpUnitImg,
-                width: 266.5,
-                height: 162,
-              ).marginOnly(top: 28, bottom: 18),
-
-              Row(
-                key: _inputKey,
-                mainAxisSize: MainAxisSize.min,
-                children: [
-                  //街区
-                  Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      MyTextView(
-                        S.current.block,
-                        marginBottom: 9,
-                        textColor: context.appColors.textBlack,
-                        fontSize: 16,
-                        isFontMedium: true,
-                      ),
-
-                      // 表单 - 街区
-                      _buildInputLayout(
-                        context,
-                        state,
-                        "block",
-                        textInputAction: TextInputAction.next,
-                        onSubmit: (formKey, value) {
-                          state.formData[formKey]!['focusNode'].unfocus();
-                          FocusScope.of(context).requestFocus(state.formData['unit']!['focusNode']);
-                        },
-                      ).constrained(width: 88),
-                    ],
-                  ),
-
-                  MyTextView(
-                    "#",
-                    marginTop: 20,
-                    marginLeft: 8.5,
-                    marginRight: 8.5,
-                    textColor: context.appColors.textBlack,
-                    fontSize: 16,
-                    isFontMedium: true,
-                  ),
-
-                  //单元
-                  Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      MyTextView(
-                        S.current.unit_number,
-                        marginBottom: 9,
-                        textColor: context.appColors.textBlack,
-                        fontSize: 16,
-                        isFontMedium: true,
-                      ),
-                      Row(
-                        children: [
-                          // 表单 - 单元
-                          _buildInputLayout(
-                            context,
-                            state,
-                            "unit",
-                            textInputAction: TextInputAction.next,
-                            onSubmit: (formKey, value) {
-                              state.formData[formKey]!['focusNode'].unfocus();
-                              FocusScope.of(context).requestFocus(state.formData['room']!['focusNode']);
-                            },
-                          ).constrained(width: 83),
-
-                          MyTextView(
-                            "-",
-                            textColor: context.appColors.textBlack,
-                            marginLeft: 4,
-                            marginRight: 4,
-                            isFontMedium: true,
-                          ),
-
-                          // 表单 - 房号
-                          _buildInputLayout(
-                            context,
-                            state,
-                            "room",
-                            textInputAction: TextInputAction.done,
-                            onSubmit: (formKey, value) {
-                              state.formData[formKey]!['focusNode'].unfocus();
-                            },
-                          ).constrained(width: 83),
-                        ],
-                      ),
-                    ],
-                  ),
-                ],
-              ),
-
-              MyTextView(
-                key: _description1Key,
-                S.current.block_desc,
-                fontSize: 15,
-                marginTop: 25,
-                textAlign: TextAlign.center,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              MyTextView(
-                key: _description2Key,
-                S.current.block_example,
-                fontSize: 15,
-                marginTop: 20,
-                textAlign: TextAlign.center,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              MyTextView(
-                key: _description3Key,
-                S.current.block_example_desc,
-                fontSize: 15,
-                marginTop: 20,
-                textAlign: TextAlign.center,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              SizedBox(
-                height: state.remainingSpace, // 使用剩余空间的值
-              ),
-
-              MyButton(
-                key: _buttonKey,
-                onPressed: viewModel.submitUnit,
-                text: S.current.next,
-                textColor: Colors.white,
-                backgroundColor: context.appColors.btnBgDefault,
-                fontWeight: FontWeight.w500,
-                type: ClickType.throttle,
-                fontSize: 16,
-                minHeight: 50,
-                radius: 5,
-              ).marginOnly(top: 40, bottom: 30, left: 18, right: 18),
-            ],
-          ),
+      body: Container(
+        padding: const EdgeInsets.symmetric(horizontal: 20),
+        width: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    //顶部图片
+                    const MyAssetImage(
+                      Assets.authSignUpUnitImg,
+                      width: 266.5,
+                      height: 162,
+                    ).marginOnly(top: 28, bottom: 18),
+
+                    Row(
+                      mainAxisSize: MainAxisSize.min,
+                      children: [
+                        //街区
+                        Column(
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              S.current.block,
+                              marginBottom: 9,
+                              textColor: context.appColors.textBlack,
+                              fontSize: 16,
+                              isFontMedium: true,
+                            ),
+
+                            // 表单 - 街区
+                            _buildInputLayout(
+                              context,
+                              state,
+                              "block",
+                              textInputAction: TextInputAction.next,
+                              onSubmit: (formKey, value) {
+                                state.formData[formKey]!['focusNode'].unfocus();
+                                FocusScope.of(context).requestFocus(state.formData['unit']!['focusNode']);
+                              },
+                            ).constrained(width: 88),
+                          ],
+                        ),
+
+                        MyTextView(
+                          "#",
+                          marginTop: 20,
+                          marginLeft: 8.5,
+                          marginRight: 8.5,
+                          textColor: context.appColors.textBlack,
+                          fontSize: 16,
+                          isFontMedium: true,
+                        ),
+
+                        //单元
+                        Column(
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              S.current.unit_number,
+                              marginBottom: 9,
+                              textColor: context.appColors.textBlack,
+                              fontSize: 16,
+                              isFontMedium: true,
+                            ),
+                            Row(
+                              children: [
+                                // 表单 - 单元
+                                _buildInputLayout(
+                                  context,
+                                  state,
+                                  "unit",
+                                  textInputAction: TextInputAction.next,
+                                  onSubmit: (formKey, value) {
+                                    state.formData[formKey]!['focusNode'].unfocus();
+                                    FocusScope.of(context).requestFocus(state.formData['room']!['focusNode']);
+                                  },
+                                ).constrained(width: 83),
+
+                                MyTextView(
+                                  "-",
+                                  textColor: context.appColors.textBlack,
+                                  marginLeft: 4,
+                                  marginRight: 4,
+                                  isFontMedium: true,
+                                ),
+
+                                // 表单 - 房号
+                                _buildInputLayout(
+                                  context,
+                                  state,
+                                  "room",
+                                  textInputAction: TextInputAction.done,
+                                  onSubmit: (formKey, value) {
+                                    state.formData[formKey]!['focusNode'].unfocus();
+                                  },
+                                ).constrained(width: 83),
+                              ],
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
+
+                    MyTextView(
+                      S.current.block_desc,
+                      fontSize: 15,
+                      marginTop: 25,
+                      textAlign: TextAlign.center,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.block_example,
+                      fontSize: 15,
+                      marginTop: 20,
+                      textAlign: TextAlign.center,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.block_example_desc,
+                      fontSize: 15,
+                      marginTop: 20,
+                      textAlign: TextAlign.center,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                )).expanded(),
+
+            MyButton(
+              onPressed: viewModel.submitUnit,
+              text: S.current.next,
+              textColor: Colors.white,
+              backgroundColor: context.appColors.btnBgDefault,
+              fontWeight: FontWeight.w500,
+              type: ClickType.throttle,
+              fontSize: 16,
+              minHeight: 50,
+              radius: 5,
+            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
+          ],
         ),
         ),
       ),
       ),
     );
     );

+ 0 - 4
packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.dart

@@ -17,8 +17,4 @@ class SelectUnitViewModel extends _$SelectUnitViewModel {
     SelectRolePage.startInstance();
     SelectRolePage.startInstance();
   }
   }
 
 
-  void setRemainingSpace(double remainingSpace) {
-    state = state.copyWith(remainingSpace: remainingSpace);
-  }
-
 }
 }

+ 0 - 92
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_full_screen.dart

@@ -1,92 +0,0 @@
-import 'package:cs_resources/generated/assets.dart';
-import 'package:cs_resources/generated/l10n.dart';
-import 'package:cs_resources/theme/app_colors_theme.dart';
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_appbar.dart';
-import 'package:widgets/my_button.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/my_text_view.dart';
-
-import '../../router/page/auth_page_router.dart';
-import 'sign_up_success_view_model.dart';
-
-//全面屏手机
-class SignUpSuccessFullScreen extends HookConsumerWidget {
-  const SignUpSuccessFullScreen({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final viewModel = ref.watch(signUpSuccessViewModelProvider.notifier);
-
-    return LayoutBuilder(
-      builder: (context, constraints) {
-        return Container(
-          padding: const EdgeInsets.symmetric(horizontal: 20),
-          width: double.infinity,
-          height: constraints.maxHeight, // 占满父容器的高度
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.start,
-            children: [
-              //顶部图片
-              const MyAssetImage(
-                Assets.authYyHomeSuccess,
-                width: 264,
-                height: 180,
-              ).alignCenter().marginOnly(top: 12),
-
-              MyTextView(
-                S.current.welcome_name("Hu yu"),
-                fontSize: 23,
-                marginTop: 30,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              MyTextView(
-                S.current.sign_up_success_txt1,
-                fontSize: 15,
-                marginTop: 25,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              MyTextView(
-                S.current.sign_up_success_txt2,
-                fontSize: 15,
-                marginTop: 20,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              MyTextView(
-                S.current.sign_up_success_txt3,
-                fontSize: 15,
-                marginTop: 20,
-                isFontMedium: true,
-                textColor: context.appColors.textBlack,
-              ),
-
-              const Spacer(),
-
-              MyButton(
-                onPressed: viewModel.gotoSelectEstatePage,
-                text: S.current.get_started,
-                textColor: Colors.white,
-                backgroundColor: context.appColors.btnBgDefault,
-                fontWeight: FontWeight.w500,
-                type: ClickType.throttle,
-                fontSize: 16,
-                minHeight: 50,
-                radius: 5,
-              ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
-            ],
-          ),
-        );
-      },
-    );
-  }
-}

+ 73 - 6
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart

@@ -1,4 +1,4 @@
-import 'package:cpt_auth/modules/sing_up_success/sign_up_success_full_screen.dart';
+import 'package:cpt_auth/modules/sing_up_success/sign_up_success_view_model.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
@@ -6,10 +6,12 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_appbar.dart';
-import 'package:widgets/responsive_widget.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
 import '../../router/page/auth_page_router.dart';
 import '../../router/page/auth_page_router.dart';
-import 'sign_up_success_small_screen.dart';
 
 
 @RoutePage()
 @RoutePage()
 class SignUpSuccessPage extends HookConsumerWidget {
 class SignUpSuccessPage extends HookConsumerWidget {
@@ -26,12 +28,77 @@ class SignUpSuccessPage extends HookConsumerWidget {
 
 
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(signUpSuccessViewModelProvider.notifier);
+
     return Scaffold(
     return Scaffold(
       appBar: MyAppBar.appBar(context, ""),
       appBar: MyAppBar.appBar(context, ""),
       backgroundColor: context.appColors.backgroundDefault,
       backgroundColor: context.appColors.backgroundDefault,
-      body: const ResponsiveWidget(
-        smallScreen: SignUpSuccessSmallScreen(),
-        smallFullScreen: SignUpSuccessFullScreen(),
+      body: Container(
+        padding: const EdgeInsets.symmetric(horizontal: 20),
+        width: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  children: [
+                    //顶部图片
+                    const MyAssetImage(
+                      Assets.authYyHomeSuccess,
+                      width: 264,
+                      height: 180,
+                    ).alignCenter().marginOnly(top: 12),
+
+                    MyTextView(
+                      S.current.welcome_name("Huyu"),
+                      fontSize: 23,
+                      marginTop: 30,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.sign_up_success_txt1,
+                      fontSize: 15,
+                      marginTop: 25,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.sign_up_success_txt2,
+                      fontSize: 15,
+                      marginTop: 20,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.sign_up_success_txt3,
+                      fontSize: 15,
+                      marginTop: 20,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                )).expanded(),
+
+            MyButton(
+              onPressed: viewModel.gotoSelectEstatePage,
+              text: S.current.get_started,
+              textColor: Colors.white,
+              backgroundColor: context.appColors.btnBgDefault,
+              fontWeight: FontWeight.w500,
+              type: ClickType.throttle,
+              fontSize: 16,
+              minHeight: 50,
+              radius: 5,
+            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
+          ],
+        ),
       ),
       ),
     );
     );
   }
   }

+ 0 - 90
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_small_screen.dart

@@ -1,90 +0,0 @@
-import 'package:cs_resources/generated/assets.dart';
-import 'package:cs_resources/generated/l10n.dart';
-import 'package:cs_resources/theme/app_colors_theme.dart';
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_appbar.dart';
-import 'package:widgets/my_button.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/my_text_view.dart';
-
-import '../../router/page/auth_page_router.dart';
-import 'sign_up_success_view_model.dart';
-
-//小屏手机
-class SignUpSuccessSmallScreen extends HookConsumerWidget {
-  const SignUpSuccessSmallScreen({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final viewModel = ref.watch(signUpSuccessViewModelProvider.notifier);
-
-    return SingleChildScrollView(
-      scrollDirection: Axis.vertical,
-      physics: const BouncingScrollPhysics(),
-      child: Container(
-        padding: const EdgeInsets.symmetric(horizontal: 20),
-        width: double.infinity,
-        child: Column(
-          mainAxisSize: MainAxisSize.max,
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            //顶部图片
-            const MyAssetImage(
-              Assets.authYyHomeSuccess,
-              width: 264,
-              height: 180,
-            ).alignCenter().marginOnly(top: 12),
-
-            MyTextView(
-              S.current.welcome_name("Huyu"),
-              fontSize: 23,
-              marginTop: 30,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              S.current.sign_up_success_txt1,
-              fontSize: 15,
-              marginTop: 25,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              S.current.sign_up_success_txt2,
-              fontSize: 15,
-              marginTop: 20,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              S.current.sign_up_success_txt3,
-              fontSize: 15,
-              marginTop: 20,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyButton(
-              onPressed: viewModel.gotoSelectEstatePage,
-              text: S.current.get_started,
-              textColor: Colors.white,
-              backgroundColor: context.appColors.btnBgDefault,
-              fontWeight: FontWeight.w500,
-              type: ClickType.throttle,
-              fontSize: 16,
-              minHeight: 50,
-              radius: 5,
-            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
-          ],
-        ),
-      ),
-    );
-  }
-}

+ 3 - 1
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_view_model.dart

@@ -1,6 +1,8 @@
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
 
+import '../select_estate/select_estate_page.dart';
+
 part 'sign_up_success_view_model.g.dart';
 part 'sign_up_success_view_model.g.dart';
 
 
 @riverpod
 @riverpod
@@ -10,6 +12,6 @@ class SignUpSuccessViewModel extends _$SignUpSuccessViewModel {
 
 
   //去选择社区的页面
   //去选择社区的页面
   void gotoSelectEstatePage() {
   void gotoSelectEstatePage() {
-    ToastEngine.show("去选择社区的页面");
+    SelectEstatePage.startInstance();
   }
   }
 }
 }

+ 53 - 100
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_page.dart

@@ -2,10 +2,8 @@ import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:auto_route/auto_route.dart';
-import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/ext/auto_router_extensions.dart';
-import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_button.dart';
@@ -28,55 +26,16 @@ class TenantDocPage extends HookConsumerWidget {
     }
     }
   }
   }
 
 
-  // 为需要测量的控件创建 GlobalKey
-  final GlobalKey _appbarKey = GlobalKey();
-  final GlobalKey _titleKey = GlobalKey();
-  final GlobalKey _descriptionKey = GlobalKey();
-  final GlobalKey _description1Key = GlobalKey();
-  final GlobalKey _description2Key = GlobalKey();
-  final GlobalKey _nineGridKey = GlobalKey();
-  final GlobalKey _buttonKey = GlobalKey();
-
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(tenantDocViewModelProvider.notifier);
     final viewModel = ref.read(tenantDocViewModelProvider.notifier);
     final state = ref.watch(tenantDocViewModelProvider);
     final state = ref.watch(tenantDocViewModelProvider);
 
 
-    // 获取屏幕高度
-    final screenHeight = MediaQuery.of(context).size.height;
-    final statusBarHeight = MediaQuery.of(context).padding.top;
-    final navigationBarHeight = MediaQuery.of(context).padding.bottom;
-
-    useEffect(() {
-      double usedHeight = 0;
-      // 组件挂载时执行,获取控件高度
-      WidgetsBinding.instance.addPostFrameCallback((_) {
-        // 获取各个控件的高度
-        usedHeight += _appbarKey.currentContext?.size?.height ?? 0;
-        usedHeight += _titleKey.currentContext?.size?.height ?? 0;
-        usedHeight += _descriptionKey.currentContext?.size?.height ?? 0;
-        usedHeight += _description1Key.currentContext?.size?.height ?? 0;
-        usedHeight += _description2Key.currentContext?.size?.height ?? 0;
-        usedHeight += _nineGridKey.currentContext?.size?.height ?? 0;
-        usedHeight += _buttonKey.currentContext?.size?.height ?? 0;
-
-        // 计算剩余空间
-        double remainingSpace = screenHeight - statusBarHeight - navigationBarHeight - usedHeight - 23 - 21;
-
-        Log.d("计算剩余空间:$remainingSpace");
-
-        if (remainingSpace > 0) {
-          // 设置一个状态来存储剩余空间的高度
-          viewModel.setRemainingSpace(remainingSpace);
-        }
-      });
-      return () {
-        // 组件卸载时执行
-      };
-    }, []);
-
     return Scaffold(
     return Scaffold(
-      appBar: MyAppBar.appBar(context, "", key: _appbarKey),
+      appBar: MyAppBar.appBar(
+        context,
+        "",
+      ),
       backgroundColor: context.appColors.backgroundDefault,
       backgroundColor: context.appColors.backgroundDefault,
       body: Container(
       body: Container(
         padding: const EdgeInsets.symmetric(horizontal: 15),
         padding: const EdgeInsets.symmetric(horizontal: 15),
@@ -85,63 +44,57 @@ class TenantDocPage extends HookConsumerWidget {
           mainAxisSize: MainAxisSize.max,
           mainAxisSize: MainAxisSize.max,
           crossAxisAlignment: CrossAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
           children: [
-            MyTextView(
-              key: _titleKey,
-              S.current.upload_documents,
-              fontSize: 23.5,
-              marginTop: 23,
-              marginBottom: 21,
-              textAlign: TextAlign.center,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              key: _descriptionKey,
-              S.current.upload_doc_desc,
-              fontSize: 15,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              key: _description1Key,
-              S.current.upload_doc_desc1,
-              fontSize: 15,
-              marginTop: 22,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              key: _description2Key,
-              S.current.upload_doc_desc2,
-              fontSize: 15,
-              marginTop: 22,
-              marginBottom: 24,
-              isFontMedium: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            ImageNineGrid(
-              key: _nineGridKey,
-              isSelectEnable: true,
-              maxImages: 3,
-              spacing: 10,
-              aspectRatio: 108 / 80,
-              initialImages: [],
-              onImagesChanged: (list) {
-                viewModel.setDocList(list);
-              },
-            ),
-
-            SizedBox(
-              height: state.remainingSpace, // 使用剩余空间的值
-            ),
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      S.current.upload_documents,
+                      fontSize: 23.5,
+                      marginTop: 23,
+                      marginBottom: 21,
+                      textAlign: TextAlign.center,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    MyTextView(
+                      S.current.upload_doc_desc,
+                      fontSize: 15,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    MyTextView(
+                      S.current.upload_doc_desc1,
+                      fontSize: 15,
+                      marginTop: 22,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    MyTextView(
+                      S.current.upload_doc_desc2,
+                      fontSize: 15,
+                      marginTop: 22,
+                      marginBottom: 24,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    ImageNineGrid(
+                      isSelectEnable: true,
+                      maxImages: 3,
+                      spacing: 10,
+                      aspectRatio: 108 / 80,
+                      initialImages: [],
+                      onImagesChanged: (list) {
+                        viewModel.setDocList(list);
+                      },
+                    ),
+                  ],
+                )).expanded(),
 
 
             //底部的按钮
             //底部的按钮
             MyButton(
             MyButton(
-              key: _buttonKey,
               onPressed: viewModel.submitDoc,
               onPressed: viewModel.submitDoc,
               text: S.current.next,
               text: S.current.next,
               textColor: Colors.white,
               textColor: Colors.white,
@@ -151,7 +104,7 @@ class TenantDocPage extends HookConsumerWidget {
               fontSize: 16,
               fontSize: 16,
               minHeight: 50,
               minHeight: 50,
               radius: 5,
               radius: 5,
-            ).marginOnly(top: 30, bottom: 30, left: 18, right: 18),
+            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
           ],
           ],
         ),
         ),
       ),
       ),

+ 0 - 4
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.dart

@@ -21,12 +21,8 @@ class TenantDocViewModel extends _$TenantDocViewModel {
 
 
   //提交文件
   //提交文件
   void submitDoc() {
   void submitDoc() {
-
     ToastEngine.show("请求接口上传文件:${state.docList}");
     ToastEngine.show("请求接口上传文件:${state.docList}");
   }
   }
 
 
-  void setRemainingSpace(double remainingSpace) {
-    state = state.copyWith(remainingSpace: remainingSpace);
-  }
 
 
 }
 }

+ 0 - 5
packages/cpt_auth/lib/router/component/auth_component_service.dart

@@ -22,11 +22,6 @@ class AuthComponentService extends AuthService {
   }
   }
 
 
   @override
   @override
-  void startResetPasswordPage() {
-    SelectEstatePage.startInstance();
-  }
-
-  @override
   void startSelectEstatePage() {
   void startSelectEstatePage() {
     SelectEstatePage.startInstance();
     SelectEstatePage.startInstance();
   }
   }

+ 284 - 0
packages/cpt_facility/lib/modules/book_confirm/book_confirm_page.dart

@@ -0,0 +1,284 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import '../../router/page/facility_page_router.dart';
+import 'book_confirm_view_model.dart';
+
+@RoutePage()
+class BookConfirmPage extends HookConsumerWidget {
+  const BookConfirmPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const BookConfirmPageRoute());
+    } else {
+      appRouter.push(const BookConfirmPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(bookConfirmViewModelProvider.notifier);
+    final state = ref.watch(bookConfirmViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Function Room",
+        showBackButton: true,
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDark,
+      body: Column(
+        children: [
+          Expanded(
+            child: SingleChildScrollView(
+              scrollDirection: Axis.vertical,
+              physics: const BouncingScrollPhysics(),
+              child: Column(
+                mainAxisSize: MainAxisSize.max,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  const SizedBox(height: 7.5),
+
+                  // 预定
+                  _buildConfirmItem(
+                    context,
+                    ref,
+                    S.current.book,
+                    Assets.facilityConfirmDateIcon,
+                    28.5,
+                    29,
+                    "Tue,24 Oct 2023",
+                    null,
+                    "05:00 PM-10:00 PM",
+                    null,
+                  ),
+
+                  // 设施
+                  _buildConfirmItem(
+                    context,
+                    ref,
+                    S.current.facility,
+                    Assets.facilityConfirmFacilityIcon,
+                    25.0,
+                    30.5,
+                    "Kids party room",
+                    null,
+                    "Blue room",
+                    null,
+                  ),
+
+                  // 付款
+                  _buildConfirmItem(
+                    context,
+                    ref,
+                    S.current.payment,
+                    Assets.facilityConfirmPaymentIcon,
+                    27.0,
+                    22.0,
+                    S.current.booking_fee,
+                    "10.80",
+                    S.current.total,
+                    "\$10.80",
+                  ),
+
+                  // 押金
+                  _buildConfirmItem(
+                    context,
+                    ref,
+                    S.current.deposit,
+                    Assets.facilityConfirmDepositIcon,
+                    28.0,
+                    26.5,
+                    S.current.deposit_hold,
+                    "\$100.00",
+                    null,
+                    null,
+                  ),
+
+                  // 添加间隔
+                  const SizedBox(height: 7.5),
+
+                ],
+              ),
+            ),
+          ),
+
+          // 显示支付信息
+          _paymentInfo(context),
+
+          // 底部按钮
+          MyButton(
+            onPressed:viewModel.doPayment,
+            text: S.current.proceed_with_payment,
+            textColor: Colors.white,
+            backgroundColor: context.appColors.btnBgDefault,
+            fontWeight: FontWeight.w500,
+            type: ClickType.throttle,
+            fontSize: 16,
+            minHeight: 50,
+            radius: 0,
+          ).marginOnly(top: 15),
+        ],
+      ),
+    );
+  }
+
+
+  //展示的Item
+  Widget _buildConfirmItem(
+    BuildContext context,
+    WidgetRef ref,
+    String title,
+    String iconPath,
+    double iconWidth,
+    double iconHeight,
+    String line1Txt,
+    String? line1Content,
+    String? line2Txt,
+    String? line2Content,
+  ) {
+    return Container(
+      width: double.infinity,
+      height: 92.5,
+      padding: const EdgeInsets.only(left: 20, right: 20),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 7.5, bottom: 7.5),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteBG,
+        borderRadius: BorderRadius.circular(6.0), // 圆角
+        boxShadow: [
+          BoxShadow(
+            color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+            offset: const Offset(0, 3), // 阴影的偏移量
+            blurRadius: 8.0, // 模糊半径
+            spreadRadius: 3.0, // 扩散半径
+          ),
+        ],
+      ),
+      child: Center(
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            MyTextView(
+              title,
+              textColor: context.appColors.textBlack,
+              fontSize: 16,
+              marginBottom: 7,
+              isFontMedium: true,
+            ),
+            Row(
+              mainAxisSize: MainAxisSize.max,
+              children: [
+                MyAssetImage(
+                  iconPath,
+                  width: iconWidth,
+                  height: iconHeight,
+                ).marginOnly(right: 15),
+                Column(
+                  mainAxisSize: MainAxisSize.min,
+                  children: [
+                    Row(
+                      children: [
+                        MyTextView(
+                          line1Txt,
+                          textColor: context.appColors.textBlack,
+                          fontSize: 14,
+                          isFontRegular: true,
+                        ).expanded(),
+                        MyTextView(
+                          line1Content ?? "",
+                          textColor: context.appColors.textBlack,
+                          fontSize: 14,
+                          isFontRegular: true,
+                        ),
+                      ],
+                    ),
+                    Visibility(
+                      visible: line2Txt != null,
+                      child: Row(
+                        children: [
+                          MyTextView(
+                            line2Txt ?? "",
+                            textColor: context.appColors.textBlack,
+                            fontSize: 14,
+                            isFontRegular: true,
+                          ).expanded(),
+                          MyTextView(
+                            line2Content ?? "",
+                            textColor: context.appColors.textBlack,
+                            fontSize: 14,
+                            isFontRegular: true,
+                          ),
+                        ],
+                      ).marginOnly(top: 6),
+                    ),
+                  ],
+                ).expanded(),
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  //底部的支付信息
+  Widget _paymentInfo(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.symmetric(vertical: 17.5, horizontal: 23),
+      color: context.appColors.whiteBG,
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          MyTextView(
+            S.current.card_caps,
+            marginBottom: 17,
+            textColor: context.appColors.textPrimary,
+            fontSize: 17,
+            isFontMedium: true,
+          ),
+          Row(
+            children: [
+              const MyAssetImage(
+                Assets.facilityConfirmEcardIcon,
+                height: 38,
+              ),
+              MyTextView(
+                "Ending 9423",
+                marginLeft: 15,
+                marginRight: 15,
+                textColor: context.appColors.textBlack,
+                fontSize: 15,
+                isFontMedium: true,
+              ).expanded(),
+              MyTextView(
+                S.current.change,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                paddingRight: 16,
+                paddingLeft: 16,
+                paddingTop: 8,
+                paddingBottom: 8,
+                cornerRadius: 7,
+                fontSize: 15,
+                isFontMedium: true,
+              )
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

+ 3 - 0
packages/cpt_facility/lib/modules/book_confirm/book_confirm_state.dart

@@ -0,0 +1,3 @@
+class BookConfirmState{
+
+}

+ 25 - 0
packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.dart

@@ -0,0 +1,25 @@
+import 'package:cpt_facility/modules/detail/facility_detail_page.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'book_confirm_state.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+
+part 'book_confirm_view_model.g.dart';
+
+@riverpod
+class BookConfirmViewModel extends _$BookConfirmViewModel {
+  @override
+  BookConfirmState build() {
+    return BookConfirmState();
+  }
+
+  //执行支付
+  void doPayment(){
+
+    ToastEngine.show("点击了确定");
+
+    FacilityDetailPage.startWithPop2Main();
+  }
+
+}

+ 27 - 0
packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'book_confirm_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$bookConfirmViewModelHash() =>
+    r'94f61f3b11ea3f6bc8baa1abaccf013230ecf2e4';
+
+/// See also [BookConfirmViewModel].
+@ProviderFor(BookConfirmViewModel)
+final bookConfirmViewModelProvider = AutoDisposeNotifierProvider<
+    BookConfirmViewModel, BookConfirmState>.internal(
+  BookConfirmViewModel.new,
+  name: r'bookConfirmViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$bookConfirmViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$BookConfirmViewModel = AutoDisposeNotifier<BookConfirmState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 176 - 26
packages/cpt_facility/lib/modules/booking/facility_booking_page.dart

@@ -1,11 +1,22 @@
+import 'dart:math';
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/select_calendar/calendar_bottom_sheet.dart';
 import 'package:widgets/widget_export.dart';
 import 'package:widgets/widget_export.dart';
 
 
 import '../../router/page/facility_page_router.dart';
 import '../../router/page/facility_page_router.dart';
@@ -29,38 +40,177 @@ class FacilityBookingPage extends HookConsumerWidget {
     final viewModel = ref.watch(facilityBookingViewModelProvider.notifier);
     final viewModel = ref.watch(facilityBookingViewModelProvider.notifier);
     final state = ref.watch(facilityBookingViewModelProvider);
     final state = ref.watch(facilityBookingViewModelProvider);
 
 
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchListByDate());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Scaffold(
     return Scaffold(
       appBar: MyAppBar.appBar(context, "Kids party room", backgroundColor: context.appColors.whiteBG),
       appBar: MyAppBar.appBar(context, "Kids party room", backgroundColor: context.appColors.whiteBG),
       backgroundColor: context.appColors.backgroundDark,
       backgroundColor: context.appColors.backgroundDark,
-      body: SingleChildScrollView(
-        scrollDirection: Axis.vertical,
-        physics: const BouncingScrollPhysics(),
-        child: Column(
-          mainAxisSize: MainAxisSize.max,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          children: [
-            MyTextView(
-              "Friday,11 October 2024",
-              textColor: context.appColors.textBlack,
-              fontSize: 17,
-              marginTop: 18,
-              marginBottom: 16,
-              marginLeft: 15,
+      body: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          //顶部的选中的日期与日历选择
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "${DateTimeUtils.getWeekday(state.selectedDate, languageCode: 'en')}, ${DateTimeUtils.formatDate(state.selectedDate, format: 'dd MMM yyyy')}",
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 18,
+                marginBottom: 16,
+                marginLeft: 15,
+                isFontMedium: true,
+              ).expanded(),
+              const MyAssetImage(Assets.facilityConfirmDateIcon, width: 22.5, height: 22.5).marginOnly(right: 10).onTap(() {
+                //日历日期选择器
+                _datePickerBottomSheet(context, ref);
+              }, padding: 5),
+            ],
+          ),
+
+          //二周的日期选择
+          WeeklyCalendar(
+            selectedDate: state.selectedDate,
+            onChangedSelectedDate: (dateTime) {
+              Log.d("onChangedSelectedDate选中 - ${dateTime}}");
+              viewModel.changeSelectedDate(dateTime);
+            },
+          ),
+
+          //每天的单独数据
+          LoadStateLayout(
+            state: state.loadingState,
+            errorMessage: state.errorMessage,
+            errorRetry: () {
+              viewModel.retryRequest();
+            },
+            successSliverWidget: [
+              SliverToBoxAdapter(
+                child: MyTextView(
+                  S.current.quota_left_msg(1, DateTimeUtils.formatDate(state.selectedDate, format: 'dd MMM yyyy')),
+                  marginTop: 7,
+                  marginBottom: 15,
+                  textColor: context.appColors.textBlack,
+                  fontSize: 12,
+                  isFontMedium: true,
+                ),
+              ),
+              SliverList(
+                  delegate: SliverChildBuilderDelegate(
+                (context, index) {
+                  return _buildFacilityOption(context, state.datas[index]);
+                },
+                childCount: state.datas.length,
+              ))
+            ],
+          ).marginOnly(top: 5).expanded(),
+
+          //底部按钮
+          MyButton(
+            onPressed: viewModel.gotoConfirmPage,
+            text: S.current.next,
+            textColor: Colors.white,
+            backgroundColor: context.appColors.btnBgDefault,
+            fontWeight: FontWeight.w500,
+            type: ClickType.throttle,
+            fontSize: 16,
+            minHeight: 50,
+            radius: 0,
+          )
+        ],
+      ),
+    );
+  }
+
+  //日期日历的选择器,底部弹窗选择
+  void _datePickerBottomSheet(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(facilityBookingViewModelProvider.notifier);
+    final state = ref.watch(facilityBookingViewModelProvider);
+
+    showModalBottomSheet<void>(
+      context: context,
+      isScrollControlled: true,
+      shape: const RoundedRectangleBorder(
+        borderRadius: BorderRadius.only(topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
+      ),
+      builder: (BuildContext context) {
+        return CustomCalendarBottomSheet(
+          firstDate: DateTime.now(),
+          lastDate: DateTime.now().add(const Duration(days: 365)),
+          selectedDate: state.selectedDate,
+          locale: "en",
+          onDateChange: (dateTime) {
+            Navigator.pop(context);
+            viewModel.changeSelectedDate(dateTime);
+          },
+        );
+      },
+    );
+  }
+
+  //生产当前设施的选项
+  Widget _buildFacilityOption(BuildContext context, String item) {
+    return Column(
+      children: [
+        Container(
+          width: double.infinity,
+          height: 38,
+          color: context.appColors.btnBgDefault,
+          child: Center(
+            child: MyTextView(
+              item,
+              fontSize: 16,
+              textColor: Colors.white,
+              textAlign: TextAlign.center,
               isFontMedium: true,
               isFontMedium: true,
             ),
             ),
-            WeeklyCalendar(
-              isAutoSelect: false,
-              selectedDate: DateTime.now().add(Duration(days: 1)),
-              onChangedSelectedDate: (dateTime) {
-                Log.d("onChangedSelectedDate选中 - ${dateTime}}");
-              },
-              onChangedPage: (dateTime, state) {
-                Log.d("onChangedPage - ${dateTime} state:${state}");
-              },
-            ),
-          ],
+          ),
         ),
         ),
-      ),
+        GridView.builder(
+          shrinkWrap: true,
+          physics: const NeverScrollableScrollPhysics(),
+          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+            crossAxisCount: 4,
+            childAspectRatio: 82 / 43,
+            mainAxisSpacing: 6.5,
+            crossAxisSpacing: 6.5,
+          ),
+          itemCount: 4,
+          itemBuilder: (context, index) {
+            return Container(
+              decoration: BoxDecoration(
+                color: context.appColors.whiteBG,
+                borderRadius: BorderRadius.circular(5.0),
+              ),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.center,
+                mainAxisAlignment: MainAxisAlignment.center, // 垂直居中
+                children: [
+                  MyTextView(
+                    "10.00 AM",
+                    fontSize: 12,
+                    textColor: context.appColors.textBlack,
+                    isFontMedium: true,
+                  ),
+                  MyTextView(
+                    "04.00 PM",
+                    fontSize: 12,
+                    textColor: context.appColors.textBlack,
+                    isFontMedium: true,
+                  ),
+                ],
+              ),
+            );
+          },
+        ).marginSymmetric(horizontal: 10, vertical: 17),
+      ],
     );
     );
   }
   }
 }
 }

+ 34 - 2
packages/cpt_facility/lib/modules/booking/facility_booking_state.dart

@@ -1,3 +1,35 @@
-class FacilityBookingState{
+import 'package:widgets/load_state_layout.dart';
 
 
-}
+class FacilityBookingState {
+  //当前选中的时间日期
+  DateTime selectedDate;
+
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  List<String> datas;
+
+  // ===================================  Begin  ↓  ===================================
+
+  FacilityBookingState({
+    required this.selectedDate,
+    this.loadingState = LoadState.State_Loading,
+    required this.datas,
+    this.errorMessage,
+  });
+
+  FacilityBookingState copyWith({
+    DateTime? selectedDate,
+    LoadState? loadingState,
+    String? errorMessage,
+    List<String>? datas,
+  }) {
+    return FacilityBookingState(
+      selectedDate: selectedDate ?? this.selectedDate,
+      loadingState: loadingState ?? this.loadingState,
+      errorMessage: errorMessage ?? this.errorMessage,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 56 - 3
packages/cpt_facility/lib/modules/booking/facility_booking_view_model.dart

@@ -1,13 +1,66 @@
+import 'package:cs_resources/generated/l10n.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/load_state_layout.dart';
+import '../book_confirm/book_confirm_page.dart';
 import 'facility_booking_state.dart';
 import 'facility_booking_state.dart';
 
 
 part 'facility_booking_view_model.g.dart';
 part 'facility_booking_view_model.g.dart';
 
 
 @riverpod
 @riverpod
-class FacilityBookingViewModel extends _$FacilityBookingViewModel{
+class FacilityBookingViewModel extends _$FacilityBookingViewModel {
   @override
   @override
   FacilityBookingState build() {
   FacilityBookingState build() {
-    return FacilityBookingState();
+    final state = FacilityBookingState(
+      selectedDate: DateTime.now(),
+      datas: [],
+    );
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+
+    return state;
+  }
+
+  //修改选中的时间
+  void changeSelectedDate(DateTime dateTime) {
+    state = state.copyWith(selectedDate: dateTime);
+    Log.d("当前选中的日期:$dateTime");
+    fetchListByDate();
+  }
+
+  //失败的重试
+  void retryRequest() {
+    fetchListByDate();
+  }
+
+  /// 获取服务器数据
+  Future fetchListByDate() async {
+    state = state.copyWith(loadingState: LoadState.State_Loading);
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    List<String> list = ["Orange Room", "Purple Room", "Red Room"];
+
+    if (list.isNotEmpty) {
+      //加载成功
+      state = state.copyWith(datas: list, loadingState: LoadState.State_Success);
+    } else {
+      //无数据
+      state = state.copyWith(datas: [], loadingState: LoadState.State_Empty);
+    }
+  }
+
+  void initListener(FacilityBookingState state) {}
+
+  void onDispose(FacilityBookingState state) {
+    Log.d("FacilityBookingViewModel - onDispose");
+  }
+
+  //去付款确认页面
+  void gotoConfirmPage() {
+    BookConfirmPage.startInstance();
   }
   }
 }
 }

+ 1 - 1
packages/cpt_facility/lib/modules/booking/facility_booking_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'facility_booking_view_model.dart';
 // **************************************************************************
 // **************************************************************************
 
 
 String _$facilityBookingViewModelHash() =>
 String _$facilityBookingViewModelHash() =>
-    r'd90fc41489be510e703686650b6027f6f6cdf77d';
+    r'c6d1d64d1d7100b6864c53327150a9893201e3a9';
 
 
 /// See also [FacilityBookingViewModel].
 /// See also [FacilityBookingViewModel].
 @ProviderFor(FacilityBookingViewModel)
 @ProviderFor(FacilityBookingViewModel)

+ 12 - 2
packages/cpt_facility/lib/modules/detail/facility_detail_page.dart

@@ -25,6 +25,16 @@ class FacilityDetailPage extends HookConsumerWidget {
     }
     }
   }
   }
 
 
+  //启动当前页面并回退至设施首页
+  static void startWithPop2Main() {
+    appRouter.pushAndPopUntil(
+      const FacilityDetailPageRoute(),
+      predicate: (route) {
+        return route.settings.name == 'FacilityPageRoute';
+      },
+    );
+  }
+
   @override
   @override
   Widget build(BuildContext context, WidgetRef ref) {
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.watch(facilityDetailViewModelProvider.notifier);
     final viewModel = ref.watch(facilityDetailViewModelProvider.notifier);
@@ -79,7 +89,7 @@ class FacilityDetailPage extends HookConsumerWidget {
               Assets.facilityConfirmPaymentIcon,
               Assets.facilityConfirmPaymentIcon,
               27.0,
               27.0,
               22.0,
               22.0,
-              "Booking Fee",
+              S.current.booking_fee,
               "10.80",
               "10.80",
               S.current.total,
               S.current.total,
               "\$10.80",
               "\$10.80",
@@ -93,7 +103,7 @@ class FacilityDetailPage extends HookConsumerWidget {
               Assets.facilityConfirmDepositIcon,
               Assets.facilityConfirmDepositIcon,
               28.0,
               28.0,
               26.5,
               26.5,
-              "On Hold",
+              S.current.on_hold,
               "\$100.00",
               "\$100.00",
               null,
               null,
               null,
               null,

+ 3 - 4
packages/cpt_facility/lib/modules/facility/history/facility_history_screen.dart

@@ -25,7 +25,7 @@ class FacilityHistoryScreen extends HookConsumerWidget {
       };
       };
     }, []);
     }, []);
 
 
-    return Container(
+    return SizedBox(
       width: double.infinity,
       width: double.infinity,
       height: double.infinity,
       height: double.infinity,
       child: EasyRefresh(
       child: EasyRefresh(
@@ -40,14 +40,13 @@ class FacilityHistoryScreen extends HookConsumerWidget {
           },
           },
           successSliverWidget: [
           successSliverWidget: [
             SliverList(
             SliverList(
-                delegate: SliverChildBuilderDelegate(
-                      (context, index) {
+                delegate: SliverChildBuilderDelegate((context, index) {
                     return FacilityHistoryItem(index: index, item: state.datas[index]).onTap((){
                     return FacilityHistoryItem(index: index, item: state.datas[index]).onTap((){
                       FacilityDetailPage.startInstance(context: context);
                       FacilityDetailPage.startInstance(context: context);
                     });
                     });
                   },
                   },
                   childCount: state.datas.length,
                   childCount: state.datas.length,
-                ))
+                )),
           ],
           ],
         ),
         ),
       ).marginOnly(top: 5, bottom: 5),
       ).marginOnly(top: 5, bottom: 5),

+ 2 - 0
packages/cpt_facility/lib/router/page/facility_page_router.dart

@@ -10,6 +10,7 @@ import '../../modules/facility/deposit/facility_deposit_screen.dart';
 import '../../modules/facility/history/facility_history_screen.dart';
 import '../../modules/facility/history/facility_history_screen.dart';
 import '../../modules/detail/facility_detail_page.dart';
 import '../../modules/detail/facility_detail_page.dart';
 import '../../modules/booking/facility_booking_page.dart';
 import '../../modules/booking/facility_booking_page.dart';
+import '../../modules/book_confirm/book_confirm_page.dart';
 
 
 part 'facility_page_router.gr.dart';
 part 'facility_page_router.gr.dart';
 
 
@@ -33,5 +34,6 @@ class FacilityPageRouter extends _$FacilityPageRouter {
         ),
         ),
         CustomRoute(page: FacilityDetailPageRoute.page, path: RouterPath.facilityDetail, transitionsBuilder: applySlideTransition),
         CustomRoute(page: FacilityDetailPageRoute.page, path: RouterPath.facilityDetail, transitionsBuilder: applySlideTransition),
         CustomRoute(page: FacilityBookingPageRoute.page, path: RouterPath.facilityBook, transitionsBuilder: applySlideTransition),
         CustomRoute(page: FacilityBookingPageRoute.page, path: RouterPath.facilityBook, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: BookConfirmPageRoute.page, path: RouterPath.facilityBookConfirm, transitionsBuilder: applySlideTransition),
       ];
       ];
 }
 }

+ 20 - 0
packages/cpt_facility/lib/router/page/facility_page_router.gr.dart

@@ -15,6 +15,12 @@ abstract class _$FacilityPageRouter extends RootStackRouter {
 
 
   @override
   @override
   final Map<String, PageFactory> pagesMap = {
   final Map<String, PageFactory> pagesMap = {
+    BookConfirmPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const BookConfirmPage(),
+      );
+    },
     FacilityActivePageRoute.name: (routeData) {
     FacilityActivePageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         routeData: routeData,
@@ -61,6 +67,20 @@ abstract class _$FacilityPageRouter extends RootStackRouter {
 }
 }
 
 
 /// generated route for
 /// generated route for
+/// [BookConfirmPage]
+class BookConfirmPageRoute extends PageRouteInfo<void> {
+  const BookConfirmPageRoute({List<PageRouteInfo>? children})
+      : super(
+          BookConfirmPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'BookConfirmPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [FacilityActiveScreen]
 /// [FacilityActiveScreen]
 class FacilityActivePageRoute extends PageRouteInfo<void> {
 class FacilityActivePageRoute extends PageRouteInfo<void> {
   const FacilityActivePageRoute({List<PageRouteInfo>? children})
   const FacilityActivePageRoute({List<PageRouteInfo>? children})

+ 1 - 1
packages/cpt_property/lib/modules/property/vm/property_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_vm.dart';
 // RiverpodGenerator
 // RiverpodGenerator
 // **************************************************************************
 // **************************************************************************
 
 
-String _$propertyVmHash() => r'9b08b5e83d2b45f67b653daf60bb66bacb9c47ed';
+String _$propertyVmHash() => r'e9f36995f10e7a4a0897046c50ff9ddd047b58d6';
 
 
 /// See also [PropertyVm].
 /// See also [PropertyVm].
 @ProviderFor(PropertyVm)
 @ProviderFor(PropertyVm)

BIN
packages/cs_resources/assets/base_lib/calendar_left_icon.webp


BIN
packages/cs_resources/assets/base_lib/calendar_right_icon.webp


+ 2 - 0
packages/cs_resources/lib/generated/assets.dart

@@ -16,6 +16,8 @@ class Assets {
   static const String authSmsVerifyImg = 'assets/auth/sms_verify_img.webp';
   static const String authSmsVerifyImg = 'assets/auth/sms_verify_img.webp';
   static const String authYyHomeSuccess = 'assets/auth/yy_home_success.webp';
   static const String authYyHomeSuccess = 'assets/auth/yy_home_success.webp';
   static const String baseLibBlackBack = 'assets/base_lib/black_back.webp';
   static const String baseLibBlackBack = 'assets/base_lib/black_back.webp';
+  static const String baseLibCalendarLeftIcon = 'assets/base_lib/calendar_left_icon.webp';
+  static const String baseLibCalendarRightIcon = 'assets/base_lib/calendar_right_icon.webp';
   static const String baseLibDialogBlueDeleteIcon = 'assets/base_lib/dialog_blue_delete_icon.webp';
   static const String baseLibDialogBlueDeleteIcon = 'assets/base_lib/dialog_blue_delete_icon.webp';
   static const String baseLibDialogDeleteIcon = 'assets/base_lib/dialog_delete_icon.webp';
   static const String baseLibDialogDeleteIcon = 'assets/base_lib/dialog_delete_icon.webp';
   static const String baseLibImageAddIcon = 'assets/base_lib/image_add_icon.webp';
   static const String baseLibImageAddIcon = 'assets/base_lib/image_add_icon.webp';

+ 10 - 2
packages/cs_resources/lib/generated/intl/messages_en.dart

@@ -24,7 +24,10 @@ class MessageLookup extends MessageLookupByLibrary {
 
 
   static String m1(count) => "${count} Characters";
   static String m1(count) => "${count} Characters";
 
 
-  static String m2(name) => "Welcome ${name}";
+  static String m2(count, date) =>
+      "You have ${count}x quota left (resets on ${date})";
+
+  static String m3(name) => "Welcome ${name}";
 
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -53,6 +56,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "booking_successful":
         "booking_successful":
             MessageLookupByLibrary.simpleMessage("BOOKING SUCCESSFUL"),
             MessageLookupByLibrary.simpleMessage("BOOKING SUCCESSFUL"),
         "cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
         "cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
+        "card_caps": MessageLookupByLibrary.simpleMessage("CARD"),
+        "change": MessageLookupByLibrary.simpleMessage("Change"),
         "change_mobile_phone":
         "change_mobile_phone":
             MessageLookupByLibrary.simpleMessage("Change Mobile Phone"),
             MessageLookupByLibrary.simpleMessage("Change Mobile Phone"),
         "characters": m1,
         "characters": m1,
@@ -177,6 +182,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "phone_email": MessageLookupByLibrary.simpleMessage("Phone/Email"),
         "phone_email": MessageLookupByLibrary.simpleMessage("Phone/Email"),
         "privacy_policy":
         "privacy_policy":
             MessageLookupByLibrary.simpleMessage("Privacy Policy"),
             MessageLookupByLibrary.simpleMessage("Privacy Policy"),
+        "proceed_with_payment":
+            MessageLookupByLibrary.simpleMessage("Proceed With Payment"),
         "property": MessageLookupByLibrary.simpleMessage("Property"),
         "property": MessageLookupByLibrary.simpleMessage("Property"),
         "property_guide":
         "property_guide":
             MessageLookupByLibrary.simpleMessage("Property Guide"),
             MessageLookupByLibrary.simpleMessage("Property Guide"),
@@ -186,6 +193,7 @@ class MessageLookup extends MessageLookupByLibrary {
             "Your feedback has been successfully sent! We will reply to you as soon as possible! thank you!"),
             "Your feedback has been successfully sent! We will reply to you as soon as possible! thank you!"),
         "published_successfully":
         "published_successfully":
             MessageLookupByLibrary.simpleMessage("Published Successfully"),
             MessageLookupByLibrary.simpleMessage("Published Successfully"),
+        "quota_left_msg": m2,
         "rate_us": MessageLookupByLibrary.simpleMessage("Rate Us"),
         "rate_us": MessageLookupByLibrary.simpleMessage("Rate Us"),
         "remove": MessageLookupByLibrary.simpleMessage("Remove"),
         "remove": MessageLookupByLibrary.simpleMessage("Remove"),
         "remove_account":
         "remove_account":
@@ -257,7 +265,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Visitor Registration"),
             MessageLookupByLibrary.simpleMessage("Visitor Registration"),
         "waiting_for_the_administrator": MessageLookupByLibrary.simpleMessage(
         "waiting_for_the_administrator": MessageLookupByLibrary.simpleMessage(
             "Waiting for the administrator"),
             "Waiting for the administrator"),
-        "welcome_name": m2,
+        "welcome_name": m3,
         "who_are_owners":
         "who_are_owners":
             MessageLookupByLibrary.simpleMessage("Who are owners?"),
             MessageLookupByLibrary.simpleMessage("Who are owners?"),
         "who_are_tenants":
         "who_are_tenants":

+ 8 - 2
packages/cs_resources/lib/generated/intl/messages_zh_CN.dart

@@ -24,7 +24,9 @@ class MessageLookup extends MessageLookupByLibrary {
 
 
   static String m1(count) => "${count} 字符";
   static String m1(count) => "${count} 字符";
 
 
-  static String m2(name) => "欢迎你 ${name}";
+  static String m2(count, date) => "你还剩余${count}次的配额 (重置于${date})";
+
+  static String m3(name) => "欢迎你 ${name}";
 
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -49,6 +51,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "booking_fee": MessageLookupByLibrary.simpleMessage("预定费用"),
         "booking_fee": MessageLookupByLibrary.simpleMessage("预定费用"),
         "booking_successful": MessageLookupByLibrary.simpleMessage("预定成功"),
         "booking_successful": MessageLookupByLibrary.simpleMessage("预定成功"),
         "cancel": MessageLookupByLibrary.simpleMessage("取消"),
         "cancel": MessageLookupByLibrary.simpleMessage("取消"),
+        "card_caps": MessageLookupByLibrary.simpleMessage("信用卡"),
+        "change": MessageLookupByLibrary.simpleMessage("更换"),
         "change_mobile_phone": MessageLookupByLibrary.simpleMessage("修改手机号码"),
         "change_mobile_phone": MessageLookupByLibrary.simpleMessage("修改手机号码"),
         "characters": m1,
         "characters": m1,
         "choose_category": MessageLookupByLibrary.simpleMessage("选择类型"),
         "choose_category": MessageLookupByLibrary.simpleMessage("选择类型"),
@@ -144,6 +148,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "privacy_policy": MessageLookupByLibrary.simpleMessage("隐私协议"),
         "privacy_policy": MessageLookupByLibrary.simpleMessage("隐私协议"),
+        "proceed_with_payment": MessageLookupByLibrary.simpleMessage("继续付款"),
         "property": MessageLookupByLibrary.simpleMessage("房产"),
         "property": MessageLookupByLibrary.simpleMessage("房产"),
         "property_guide": MessageLookupByLibrary.simpleMessage("物业指南"),
         "property_guide": MessageLookupByLibrary.simpleMessage("物业指南"),
         "property_news": MessageLookupByLibrary.simpleMessage("资产新闻"),
         "property_news": MessageLookupByLibrary.simpleMessage("资产新闻"),
@@ -151,6 +156,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "published_successful_txt":
         "published_successful_txt":
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
+        "quota_left_msg": m2,
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
         "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "remove_account": MessageLookupByLibrary.simpleMessage("移除账号"),
         "remove_account": MessageLookupByLibrary.simpleMessage("移除账号"),
@@ -209,7 +215,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "visitor_registration": MessageLookupByLibrary.simpleMessage("访客登记"),
         "visitor_registration": MessageLookupByLibrary.simpleMessage("访客登记"),
         "waiting_for_the_administrator":
         "waiting_for_the_administrator":
             MessageLookupByLibrary.simpleMessage("等待管理员回复"),
             MessageLookupByLibrary.simpleMessage("等待管理员回复"),
-        "welcome_name": m2,
+        "welcome_name": m3,
         "who_are_owners": MessageLookupByLibrary.simpleMessage("怎样才算业主?"),
         "who_are_owners": MessageLookupByLibrary.simpleMessage("怎样才算业主?"),
         "who_are_tenants": MessageLookupByLibrary.simpleMessage("怎样才算租户?"),
         "who_are_tenants": MessageLookupByLibrary.simpleMessage("怎样才算租户?"),
         "yes": MessageLookupByLibrary.simpleMessage("是"),
         "yes": MessageLookupByLibrary.simpleMessage("是"),

+ 8 - 2
packages/cs_resources/lib/generated/intl/messages_zh_HK.dart

@@ -24,7 +24,9 @@ class MessageLookup extends MessageLookupByLibrary {
 
 
   static String m1(count) => "${count} 字符";
   static String m1(count) => "${count} 字符";
 
 
-  static String m2(name) => "欢迎你 ${name}";
+  static String m2(count, date) => "你还剩余${count}次的配额 (重置于${date})";
+
+  static String m3(name) => "欢迎你 ${name}";
 
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -49,6 +51,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "booking_fee": MessageLookupByLibrary.simpleMessage("预定费用"),
         "booking_fee": MessageLookupByLibrary.simpleMessage("预定费用"),
         "booking_successful": MessageLookupByLibrary.simpleMessage("预定成功"),
         "booking_successful": MessageLookupByLibrary.simpleMessage("预定成功"),
         "cancel": MessageLookupByLibrary.simpleMessage("取消"),
         "cancel": MessageLookupByLibrary.simpleMessage("取消"),
+        "card_caps": MessageLookupByLibrary.simpleMessage("信用卡"),
+        "change": MessageLookupByLibrary.simpleMessage("更换"),
         "change_mobile_phone": MessageLookupByLibrary.simpleMessage("修改手机号码"),
         "change_mobile_phone": MessageLookupByLibrary.simpleMessage("修改手机号码"),
         "characters": m1,
         "characters": m1,
         "choose_category": MessageLookupByLibrary.simpleMessage("选择类型"),
         "choose_category": MessageLookupByLibrary.simpleMessage("选择类型"),
@@ -136,6 +140,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "payment": MessageLookupByLibrary.simpleMessage("支付"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "phone_email": MessageLookupByLibrary.simpleMessage("电话或邮箱"),
         "privacy_policy": MessageLookupByLibrary.simpleMessage("隐私协议"),
         "privacy_policy": MessageLookupByLibrary.simpleMessage("隐私协议"),
+        "proceed_with_payment": MessageLookupByLibrary.simpleMessage("继续付款"),
         "property": MessageLookupByLibrary.simpleMessage("房产"),
         "property": MessageLookupByLibrary.simpleMessage("房产"),
         "property_guide": MessageLookupByLibrary.simpleMessage("物业指南"),
         "property_guide": MessageLookupByLibrary.simpleMessage("物业指南"),
         "property_news": MessageLookupByLibrary.simpleMessage("资产新闻"),
         "property_news": MessageLookupByLibrary.simpleMessage("资产新闻"),
@@ -143,6 +148,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "published_successful_txt":
         "published_successful_txt":
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
+        "quota_left_msg": m2,
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
         "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "remove_account": MessageLookupByLibrary.simpleMessage("移除账号"),
         "remove_account": MessageLookupByLibrary.simpleMessage("移除账号"),
@@ -196,7 +202,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "visitor_registration": MessageLookupByLibrary.simpleMessage("访客登记"),
         "visitor_registration": MessageLookupByLibrary.simpleMessage("访客登记"),
         "waiting_for_the_administrator":
         "waiting_for_the_administrator":
             MessageLookupByLibrary.simpleMessage("等待管理员回复"),
             MessageLookupByLibrary.simpleMessage("等待管理员回复"),
-        "welcome_name": m2,
+        "welcome_name": m3,
         "yes": MessageLookupByLibrary.simpleMessage("是"),
         "yes": MessageLookupByLibrary.simpleMessage("是"),
         "you_have": MessageLookupByLibrary.simpleMessage("你还有"),
         "you_have": MessageLookupByLibrary.simpleMessage("你还有"),
         "your_roles_responsibilities":
         "your_roles_responsibilities":

+ 40 - 0
packages/cs_resources/lib/generated/l10n.dart

@@ -1680,6 +1680,46 @@ class S {
     );
     );
   }
   }
 
 
+  /// `You have {count}x quota left (resets on {date})`
+  String quota_left_msg(Object count, Object date) {
+    return Intl.message(
+      'You have ${count}x quota left (resets on $date)',
+      name: 'quota_left_msg',
+      desc: '',
+      args: [count, date],
+    );
+  }
+
+  /// `CARD`
+  String get card_caps {
+    return Intl.message(
+      'CARD',
+      name: 'card_caps',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Change`
+  String get change {
+    return Intl.message(
+      'Change',
+      name: 'change',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Proceed With Payment`
+  String get proceed_with_payment {
+    return Intl.message(
+      'Proceed With Payment',
+      name: 'proceed_with_payment',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Other`
   /// `Other`
   String get other {
   String get other {
     return Intl.message(
     return Intl.message(

+ 4 - 0
packages/cs_resources/lib/l10n/intl_en.arb

@@ -162,5 +162,9 @@
   "booking_fee": "Booking Fee",
   "booking_fee": "Booking Fee",
   "on_hold": "On Hold",
   "on_hold": "On Hold",
   "total": "Total",
   "total": "Total",
+  "quota_left_msg": "You have {count}x quota left (resets on {date})",
+  "card_caps": "CARD",
+  "change": "Change",
+  "proceed_with_payment": "Proceed With Payment",
   "other": "Other"
   "other": "Other"
 }
 }

+ 4 - 0
packages/cs_resources/lib/l10n/intl_zh_CN.arb

@@ -162,5 +162,9 @@
   "booking_fee": "预定费用",
   "booking_fee": "预定费用",
   "on_hold": "持有",
   "on_hold": "持有",
   "total": "共计",
   "total": "共计",
+  "quota_left_msg": "你还剩余{count}次的配额 (重置于{date})",
+  "card_caps": "信用卡",
+  "change": "更换",
+  "proceed_with_payment": "继续付款",
   "other": "其他"
   "other": "其他"
 }
 }

+ 4 - 0
packages/cs_resources/lib/l10n/intl_zh_HK.arb

@@ -148,5 +148,9 @@
   "booking_fee": "预定费用",
   "booking_fee": "预定费用",
   "on_hold": "持有",
   "on_hold": "持有",
   "total": "共计",
   "total": "共计",
+  "quota_left_msg": "你还剩余{count}次的配额 (重置于{date})",
+  "card_caps": "信用卡",
+  "change": "更换",
+  "proceed_with_payment": "继续付款",
   "other": "其他"
   "other": "其他"
 }
 }

+ 0 - 2
packages/cs_router/lib/componentRouter/auth_service.dart

@@ -5,7 +5,5 @@ abstract class AuthService {
 
 
   void startLoginPage();
   void startLoginPage();
 
 
-  void startResetPasswordPage();
-
   void startSelectEstatePage();
   void startSelectEstatePage();
 }
 }

+ 1 - 0
packages/cs_router/lib/path/router_path.dart

@@ -58,6 +58,7 @@ class RouterPath {
   static const facility = '/facility';
   static const facility = '/facility';
   static const facilityDetail = '/facility/detail';
   static const facilityDetail = '/facility/detail';
   static const facilityBook = '/facility/book';
   static const facilityBook = '/facility/book';
+  static const facilityBookConfirm = '/facility/book/confirm';
 
 
   //表单
   //表单
   static const form = '/form';
   static const form = '/form';

+ 49 - 0
packages/cs_widgets/lib/shatter/select_calendar/calendar_bottom_sheet.dart

@@ -0,0 +1,49 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'full_calendar.dart';
+
+class CustomCalendarBottomSheet extends StatelessWidget {
+  final DateTime firstDate;
+  final DateTime? lastDate;
+  final String locale;
+  final DateTime selectedDate;
+  final Function(DateTime) onDateChange;
+
+  const CustomCalendarBottomSheet({
+    Key? key,
+    required this.firstDate,
+    this.lastDate,
+    required this.selectedDate,
+    required this.locale,
+    required this.onDateChange,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      children: [
+        const SizedBox(height: 20),
+        Container(
+          width: 60,
+          height: 6,
+          decoration: BoxDecoration(borderRadius: BorderRadius.circular(3.0), color: const Color(0xFFE0E0E0)),
+        ),
+        const SizedBox(height: 13.0),
+        FullCalendar(
+          startDate: firstDate,
+          endDate: lastDate,
+          selectedDate: selectedDate,
+          padding: 25,
+          locale: locale,
+          dateColor: context.appColors.textBlack,
+          dateSelectedBg: context.appColors.btnBgDefault,
+          dateSelectedColor: Colors.white,
+          events: [],
+          onDateChange: onDateChange,
+        ),
+      ],
+    );
+  }
+}

+ 336 - 0
packages/cs_widgets/lib/shatter/select_calendar/full_calendar.dart

@@ -0,0 +1,336 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:intl/intl.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+
+//日历的具体展示
+class FullCalendar extends StatefulWidget {
+  final DateTime startDate;
+  final DateTime? endDate;
+  final DateTime? selectedDate;
+  final Color? dateColor;
+  final Color? dateSelectedColor;
+  final Color? dateSelectedBg;
+  final double? padding;
+  final String? locale;
+  final Widget? calendarBackground;
+  final List<String>? events;
+  final Function onDateChange;
+
+  const FullCalendar({
+    Key? key,
+    this.endDate,
+    required this.startDate,
+    required this.padding,
+    required this.onDateChange,
+    this.calendarBackground,
+    this.events,
+    this.dateColor,
+    this.dateSelectedColor,
+    this.dateSelectedBg,
+    this.locale,
+    this.selectedDate,
+  }) : super(key: key);
+
+  @override
+  State<FullCalendar> createState() => _FullCalendarState();
+}
+
+class _FullCalendarState extends State<FullCalendar> {
+  late DateTime endDate;
+
+  late DateTime startDate;
+  late int _initialPage;
+
+  List<String>? _events = [];
+
+  late PageController _horizontalScroll;
+
+  @override
+  void initState() {
+    setState(() {
+      startDate = DateTime.parse("${widget.startDate.toString().split(" ").first} 00:00:00.000");
+
+      endDate = DateTime.parse("${widget.endDate.toString().split(" ").first} 23:00:00.000");
+
+      _events = widget.events;
+    });
+
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    List<String> partsStart = startDate.toString().split(" ").first.split("-");
+
+    DateTime firstDate = DateTime.parse("${partsStart.first}-${partsStart[1].padLeft(2, '0')}-01 00:00:00.000");
+
+    List<String> partsEnd = endDate.toString().split(" ").first.split("-");
+
+    DateTime lastDate =
+        DateTime.parse("${partsEnd.first}-${(int.parse(partsEnd[1]) + 1).toString().padLeft(2, '0')}-01 23:00:00.000").subtract(const Duration(days: 1));
+
+    double width = MediaQuery.of(context).size.width - (2 * widget.padding!);
+
+    List<DateTime?> dates = [];
+
+    DateTime referenceDate = firstDate;
+
+    while (referenceDate.isBefore(lastDate)) {
+      List<String> referenceParts = referenceDate.toString().split(" ");
+      DateTime newDate = DateTime.parse("${referenceParts.first} 12:00:00.000");
+      dates.add(newDate);
+
+      referenceDate = newDate.add(const Duration(days: 1));
+    }
+
+    if (firstDate.year == lastDate.year && firstDate.month == lastDate.month) {
+      return Padding(
+        padding: EdgeInsets.fromLTRB(widget.padding!, 40.0, widget.padding!, 0.0),
+        child: month(dates, width, widget.locale),
+      );
+    } else {
+      List<DateTime?> months = [];
+      for (int i = 0; i < dates.length; i++) {
+        if (i == 0 || (dates[i]!.month != dates[i - 1]!.month)) {
+          months.add(dates[i]);
+        }
+      }
+
+      months.sort((b, a) => a!.compareTo(b!));
+
+      final index = months.indexWhere((element) => element!.month == widget.selectedDate!.month && element.year == widget.selectedDate!.year);
+
+      _initialPage = index;
+      _horizontalScroll = PageController(initialPage: _initialPage);
+
+      double monthHeight = 6 * (width / 7) + 16 + 10 + 10 + 80; // 固定高度,6行的高度加上80额外空间
+
+      return Container(
+        height: monthHeight, // 使用固定的高度
+        padding: const EdgeInsets.fromLTRB(25, 10.0, 25, 20.0),
+        //只是PageView
+        child: Stack(
+          children: [
+            //主题
+            PageView.builder(
+              physics: const BouncingScrollPhysics(),
+              controller: _horizontalScroll,
+              reverse: true,
+              scrollDirection: Axis.horizontal,
+              itemCount: months.length,
+              itemBuilder: (context, index) {
+                DateTime? date = months[index];
+                List<DateTime?> daysOfMonth = [];
+                for (var item in dates) {
+                  if (date!.month == item!.month && date.year == item.year) {
+                    daysOfMonth.add(item);
+                  }
+                }
+
+                bool isLast = index == 0;
+
+                return Container(
+                  padding: EdgeInsets.only(bottom: isLast ? 0.0 : 10.0),
+                  child: month(daysOfMonth, width, widget.locale),
+                );
+              },
+            ),
+
+            //返回按钮
+            Positioned(
+              top: -11,
+              width: MediaQuery.of(context).size.width * 0.88,
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  const MyAssetImage(
+                    Assets.baseLibCalendarLeftIcon,
+                    width: 44,
+                    height: 44,
+                  ).onTap(() {
+                    _horizontalScroll.nextPage(
+                      duration: const Duration(milliseconds: 300),
+                      curve: Curves.ease,
+                    );
+                  }),
+                  const MyAssetImage(
+                    Assets.baseLibCalendarRightIcon,
+                    width: 44,
+                    height: 44,
+                  ).onTap(() {
+                    _horizontalScroll.previousPage(
+                      duration: const Duration(milliseconds: 300),
+                      curve: Curves.ease,
+                    );
+                  }),
+                ],
+              ),
+            )
+          ],
+        ),
+      );
+    }
+  }
+
+  //顶部星期的文本数据
+  Widget daysOfWeek(double width, String? locale) {
+    List daysNames = [];
+    for (var day = 12; day <= 18; day++) {
+      daysNames.add(DateFormat.E(locale.toString()).format(DateTime.parse('1970-01-$day')));
+    }
+
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+      children: [
+        dayName(width / 7, daysNames[0]),
+        dayName(width / 7, daysNames[1]),
+        dayName(width / 7, daysNames[2]),
+        dayName(width / 7, daysNames[3]),
+        dayName(width / 7, daysNames[4]),
+        dayName(width / 7, daysNames[5]),
+        dayName(width / 7, daysNames[6]),
+      ],
+    );
+  }
+
+  //顶部星期的文本控件展示
+  Widget dayName(double width, String text) {
+    return Container(
+      width: width,
+      alignment: Alignment.center,
+      child: Text(
+        text,
+        style: const TextStyle(
+          fontSize: 13.0,
+          fontWeight: FontWeight.w500,
+        ),
+        overflow: TextOverflow.ellipsis,
+      ),
+    );
+  }
+
+  //当前月份,每一天的布局
+  Widget dateInCalendar(DateTime date, bool outOfRange, double width, bool event) {
+    bool isSelectedDate = date.toString().split(" ").first == widget.selectedDate.toString().split(" ").first;
+    return GestureDetector(
+      onTap: () => outOfRange ? null : widget.onDateChange(date),
+      child: Container(
+        width: width / 7,
+        height: width / 7,
+        decoration: BoxDecoration(
+          shape: BoxShape.circle,
+          color: isSelectedDate ? widget.dateSelectedBg : Colors.transparent,
+        ),
+        alignment: Alignment.center,
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            const SizedBox(
+              height: 5.0,
+            ),
+            Padding(
+              padding: const EdgeInsets.symmetric(vertical: 4.0),
+              child: Text(
+                DateFormat("dd").format(date),
+                style: TextStyle(
+                    color: outOfRange
+                        ? isSelectedDate
+                            ? widget.dateSelectedColor!.withOpacity(0.9)
+                            : widget.dateColor!.withOpacity(0.4)
+                        : isSelectedDate
+                            ? widget.dateSelectedColor
+                            : widget.dateColor,
+                    fontWeight: FontWeight.w500,
+                    fontSize: 13),
+              ),
+            ),
+            event
+                ? Icon(
+                    Icons.bookmark,
+                    size: 8,
+                    color: isSelectedDate ? widget.dateSelectedColor : widget.dateSelectedBg,
+                  )
+                : const SizedBox(height: 5.0),
+          ],
+        ),
+      ),
+    );
+  }
+
+  //单独一个月的Page布局
+  Widget month(List dates, double width, String? locale) {
+    DateTime first = dates.first;
+
+    // 获取这个月的第一天
+    DateTime firstDayOfMonth = DateTime(first.year, first.month, 1);
+
+    // 找到这个月的第一天是星期几
+    int firstWeekday = firstDayOfMonth.weekday;
+
+    // 计算需要的前导空格数量
+    int leadingDaysCount = (firstWeekday - DateTime.monday + 7) % 7;
+
+    // 只保留当前月份的日期
+    List<DateTime?> fullDates = List.from(dates);
+
+    // 在视图中添加用于填充的空日期(如果需要,这里就不填充上个月尾的日期了)
+    for (int i = 0; i < leadingDaysCount; i++) {
+      fullDates.insert(0, null); // 用null填充前导位置
+    }
+
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.start,
+      children: [
+        Text(
+          DateFormat.yMMMM(Locale(locale!).toString()).format(first),
+          style: TextStyle(fontSize: 18.0, color: widget.dateColor, fontWeight: FontWeight.w500),
+        ),
+
+        // 周一到周天的星期文本
+        Padding(
+          padding: const EdgeInsets.only(top: 30.0),
+          child: daysOfWeek(width, widget.locale),
+        ),
+
+        // 底部的每月的每一天
+        Container(
+          padding: const EdgeInsets.only(top: 10.0),
+          height: (fullDates.length > 28)
+              ? (fullDates.length > 35 ? 6.2 * width / 7 : 5.2 * width / 7)
+              : 4 * width / 7,
+          width: MediaQuery.of(context).size.width - 2 * widget.padding!,
+          child: GridView.builder(
+            itemCount: fullDates.length,
+            physics: const NeverScrollableScrollPhysics(),
+            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
+            itemBuilder: (context, index) {
+              DateTime? date = fullDates[index]; // 使用 DateTime? 类型以支持 null
+
+              // 如果 date 为 null,表示该位置为空,返回一个透明的容器
+              if (date == null) {
+                return Container(
+                  width: width / 7,
+                  height: width / 7,
+                  color: Colors.transparent, // 透明或其他样式
+                );
+              }
+
+              bool outOfRange = date.isBefore(startDate) || date.isAfter(endDate);
+
+              return dateInCalendar(
+                date,
+                outOfRange,
+                width,
+                _events!.contains(date.toString().split(" ").first) && !outOfRange,
+              );
+            },
+          ),
+        )
+      ],
+    );
+  }
+
+}

+ 32 - 10
packages/cs_widgets/lib/shatter/weekly_calendar/calendar_utils.dart

@@ -1,3 +1,5 @@
+import 'package:shared/utils/date_time_utils.dart';
+
 DateTime addDay(DateTime date, int days) {
 DateTime addDay(DateTime date, int days) {
   return date.add(Duration(days: days));
   return date.add(Duration(days: days));
 }
 }
@@ -6,11 +8,35 @@ DateTime subtractDay(DateTime date, int days) {
   return date.subtract(Duration(days: days));
   return date.subtract(Duration(days: days));
 }
 }
 
 
+//一周的第一天从哪里开始,Sun 还是 Mon
 DateTime firstDayOfWeek(DateTime date) {
 DateTime firstDayOfWeek(DateTime date) {
-  if (date.weekday == DateTime.sunday) {
-    return date;
+  //返回星期天开始
+  // if (date.weekday == DateTime.sunday) {
+  //   return date;
+  // }
+  // return date.subtract(Duration(days: date.weekday));
+
+  // 从星期一开始
+  return date.subtract(Duration(days: date.weekday - 1));
+}
+
+//是否包含选中的日期
+bool hasSelectedDate(List<DateTime> list, DateTime selected) {
+  for (DateTime date in list) {
+    // 格式化日期并进行比较
+    if (DateTimeUtils.formatDate(date, format: 'yyyyMMdd') == DateTimeUtils.formatDate(selected, format: 'yyyyMMdd')) {
+      return true;
+    }
   }
   }
-  return date.subtract(Duration(days: date.weekday));
+  return false;
+}
+
+// 检查日期是否小于今天
+bool isPastDate(DateTime now, DateTime date) {
+  // 获取当前日期的凌晨时间
+  DateTime todayMidnight = DateTime(now.year, now.month, now.day);
+  // 判断给定日期是否小于今天的凌晨时间
+  return date.isBefore(todayMidnight);
 }
 }
 
 
 // ===================================  获取一周的数据  ↓  ===================================
 // ===================================  获取一周的数据  ↓  ===================================
@@ -35,9 +61,7 @@ List<DateTime> _subtractWeek(DateTime date, int subtract) {
 }
 }
 
 
 List<DateTime> _getWeekDaysAt(DateTime date) {
 List<DateTime> _getWeekDaysAt(DateTime date) {
-  return List.generate(7, (index) => index)
-      .map((index) => date.add(Duration(days: index)))
-      .toList();
+  return List.generate(7, (index) => index).map((index) => date.add(Duration(days: index))).toList();
 }
 }
 
 
 // ===================================  获取二周的数据  ↓  ===================================
 // ===================================  获取二周的数据  ↓  ===================================
@@ -62,7 +86,5 @@ List<DateTime> _subtract2Week(DateTime date, int subtract) {
 }
 }
 
 
 List<DateTime> _get2WeekDaysAt(DateTime date) {
 List<DateTime> _get2WeekDaysAt(DateTime date) {
-  return List.generate(14, (index) => index)
-      .map((index) => date.add(Duration(days: index)))
-      .toList();
-}
+  return List.generate(14, (index) => index).map((index) => date.add(Duration(days: index))).toList();
+}

+ 5 - 6
packages/cs_widgets/lib/shatter/weekly_calendar/day_cell.dart

@@ -1,6 +1,7 @@
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/date_time_utils.dart';
+import 'calendar_utils.dart';
 
 
 class DayCell extends StatelessWidget {
 class DayCell extends StatelessWidget {
   const DayCell({
   const DayCell({
@@ -26,8 +27,8 @@ class DayCell extends StatelessWidget {
       width: 40,
       width: 40,
       height: 40,
       height: 40,
       decoration: BoxDecoration(
       decoration: BoxDecoration(
-        color: _isPastDate(display)
-            ? context.appColors.disEnableGray // 小于今天的日期背景颜色,禁用
+        color: isPastDate(current,display)
+            ? context.appColors.disEnableGray.withOpacity(0.6) // 小于今天的日期背景颜色,禁用
             : _isSelected(display)
             : _isSelected(display)
                 ? _isToday(display)
                 ? _isToday(display)
                     ? context.appColors.btnBgDefault // 今天的日期背景颜色
                     ? context.appColors.btnBgDefault // 今天的日期背景颜色
@@ -79,8 +80,6 @@ class DayCell extends StatelessWidget {
     return DateTimeUtils.formatDate(date, format: 'yyyyMMdd') == DateTimeUtils.formatDate(current, format: 'yyyyMMdd');
     return DateTimeUtils.formatDate(date, format: 'yyyyMMdd') == DateTimeUtils.formatDate(current, format: 'yyyyMMdd');
   }
   }
 
 
-  // 检查日期是否小于今天
-  bool _isPastDate(DateTime date) {
-    return date.isBefore(DateTime.now().subtract(const Duration(days: 1))); // 小于今天
-  }
+
+
 }
 }

+ 5 - 9
packages/cs_widgets/lib/shatter/weekly_calendar/day_table_view.dart

@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
+import 'calendar_utils.dart';
 import 'day_cell.dart';
 import 'day_cell.dart';
 
 
 /// 一周的数据为一行,展示两周共两行
 /// 一周的数据为一行,展示两周共两行
@@ -24,9 +25,9 @@ class DayTableView extends StatelessWidget {
         Row(
         Row(
           mainAxisAlignment: MainAxisAlignment.spaceAround,
           mainAxisAlignment: MainAxisAlignment.spaceAround,
           children: weekdays.sublist(0, 7).map(
           children: weekdays.sublist(0, 7).map(
-                (date) {
+            (date) {
               return GestureDetector(
               return GestureDetector(
-                onTap: _isPastDate(date) ? null : () => onSelect?.call(date),
+                onTap: isPastDate(currentDate, date) ? null : () => onSelect?.call(date),
                 child: SizedBox(
                 child: SizedBox(
                   width: 40,
                   width: 40,
                   height: 40,
                   height: 40,
@@ -47,9 +48,9 @@ class DayTableView extends StatelessWidget {
         Row(
         Row(
           mainAxisAlignment: MainAxisAlignment.spaceAround,
           mainAxisAlignment: MainAxisAlignment.spaceAround,
           children: weekdays.sublist(7, 14).map(
           children: weekdays.sublist(7, 14).map(
-                (date) {
+            (date) {
               return GestureDetector(
               return GestureDetector(
-                onTap: _isPastDate(date) ? null : () => onSelect?.call(date),
+                onTap: isPastDate(currentDate, date) ? null : () => onSelect?.call(date),
                 child: SizedBox(
                 child: SizedBox(
                   width: 40,
                   width: 40,
                   height: 40,
                   height: 40,
@@ -66,9 +67,4 @@ class DayTableView extends StatelessWidget {
       ],
       ],
     );
     );
   }
   }
-
-  // 检查日期是否小于今天
-  bool _isPastDate(DateTime date) {
-    return date.isBefore(DateTime.now().subtract(const Duration(days: 1))); // 小于今天
-  }
 }
 }

+ 203 - 151
packages/cs_widgets/lib/shatter/weekly_calendar/week_page.dart

@@ -1,151 +1,203 @@
-import 'package:flutter/material.dart';
-import 'calendar_utils.dart' show get2Weekdays, addDay, subtractDay, firstDayOfWeek;
-import 'day_table_view.dart';
-
-enum PageState {
-  previous,
-  current,
-  next,
-}
-
-/// 一周的Days的PageView页面
-class WeekPage extends StatefulWidget {
-  const WeekPage({
-    super.key,
-    required this.selectedDate,
-    required this.now,
-    required this.isAutoSelect,
-    this.onChangedSelectedDate,
-    this.onChangedPage,
-  });
-
-  final DateTime now;
-  final DateTime selectedDate;
-  final bool isAutoSelect;
-
-  final Function(DateTime)? onChangedSelectedDate; //选择日期变化的监听
-  final Function(DateTime date, PageState state)? onChangedPage; //切换日期Page的监听
-
-  final double height = 40 + 40 + 10;
-
-  @override
-  State<StatefulWidget> createState() => _WeekPageState();
-}
-
-class _WeekPageState extends State<WeekPage> {
-  double get height => widget.height;
-  final int initialPage = 999;
-  List<int> pageCounts = [0, 1, 2];
-  int currentPage = 1;
-  late DateTime _currentPageDate;
-  late DateTime _slectedDate;
-
-  DateTime get now => widget.now;
-
-  DateTime get selectedDate => widget.selectedDate;
-
-  @override
-  void initState() {
-    super.initState();
-    _currentPageDate = selectedDate;
-    _slectedDate = selectedDate;
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Flexible(
-      child: AnimatedSize(
-        duration: const Duration(milliseconds: 250),
-        curve: Curves.easeInOut,
-        alignment: Alignment.topCenter,
-        child: SizedBox(
-          height: height,
-          child: pageViewBuilder(),
-        ),
-      ),
-    );
-  }
-
-  //PageView的方式展示不同的星期,每周每一个Page
-  Widget pageViewBuilder() {
-    final PageController pageController = PageController(initialPage: initialPage);
-    return PageView.builder(
-      itemBuilder: (context, index) {
-        final idx = _getIndex(index);
-        return dayTable(idx);
-      },
-      onPageChanged: onPageChanged,
-      controller: pageController,
-    );
-  }
-
-  //两周的数据
-  Widget dayTable(int index) {
-    int at = pageCounts[index] - 1;
-    final weekdays = get2Weekdays(now, at);
-    return DayTableView(
-      weekdays: weekdays,
-      onSelect: (date) {
-        setState(() {
-          _slectedDate = date;
-        });
-        //主动点击之后回调
-        widget.onChangedSelectedDate?.call(date);
-      },
-      selectedDate: _slectedDate,
-      currentDate: now,
-    );
-  }
-
-  //是否需要切换页面的时候自动选中
-  void changeSelectedDate(int value) {
-    if (_pageState(value) == PageState.next) {
-      if (widget.isAutoSelect) {
-        _slectedDate = addDay(selectedDate, 14);
-        widget.onChangedSelectedDate?.call(_slectedDate);
-      }
-    } else {
-      if (widget.isAutoSelect) {
-        _slectedDate = subtractDay(selectedDate, 14);
-        widget.onChangedSelectedDate?.call(_slectedDate);
-      }
-    }
-  }
-
-  //当切换页面的时候更新当前页面数据,返回当前页面第一条数据的日期
-  void updateCurrentPageDate(int value) {
-    final first = firstDayOfWeek(_currentPageDate);
-
-    if (_pageState(value) == PageState.next) {
-      _currentPageDate = addDay(first, 14);
-      widget.onChangedPage?.call(_currentPageDate, PageState.next);
-    } else {
-      _currentPageDate = subtractDay(first, 14);
-      widget.onChangedPage?.call(_currentPageDate, PageState.previous);
-    }
-  }
-
-  void onPageChanged(int value) {
-    changeSelectedDate(value);
-    updateCurrentPageDate(value);
-
-    int currentIndex = _getIndex(value);
-    int leftIndex = (currentIndex - 1 < 0) ? pageCounts.length - 1 : currentIndex - 1;
-    int rightIndex = (currentIndex + 1 > pageCounts.length - 1) ? 0 : currentIndex + 1;
-
-    pageCounts[leftIndex] = pageCounts[currentIndex] - 1;
-    pageCounts[rightIndex] = pageCounts[currentIndex] + 1;
-
-    currentPage = pageCounts[currentIndex];
-  }
-
-  int _getIndex(int idx) {
-    return (idx + 1) % pageCounts.length;
-  }
-
-  PageState _pageState(int idx) {
-    final prePage = currentPage;
-    final current = pageCounts[_getIndex(idx)];
-    return (prePage < current) ? PageState.next : PageState.previous;
-  }
-}
+// import 'package:flutter/material.dart';
+// import 'package:shared/utils/log_utils.dart';
+// import 'calendar_utils.dart' show get2Weekdays, addDay, subtractDay, firstDayOfWeek;
+// import 'day_table_view.dart';
+//
+// enum PageState {
+//   previous,
+//   current,
+//   next,
+// }
+//
+// /// 一周的Days的PageView页面
+// class WeekPage extends StatefulWidget {
+//   const WeekPage({
+//     super.key,
+//     required this.selectedDate,
+//     required this.now,
+//     required this.isAutoSelect,
+//     this.onChangedSelectedDate,
+//     this.onChangedPage,
+//   });
+//
+//   final DateTime now;
+//   final DateTime selectedDate;
+//   final bool isAutoSelect;
+//
+//   final Function(DateTime)? onChangedSelectedDate; //选择日期变化的监听
+//   final Function(DateTime date, PageState state)? onChangedPage; //切换日期Page的监听
+//
+//   final double height = 40 + 40 + 10;
+//
+//   @override
+//   State<StatefulWidget> createState() => _WeekPageState();
+// }
+//
+// class _WeekPageState extends State<WeekPage> {
+//   double get height => widget.height;
+//   final int initialPage = 999;
+//   List<int> pageCounts = [0, 1, 2];
+//   int currentPage = 1;
+//   late DateTime _currentPageDate;
+//   late DateTime _slectedDate;
+//
+//   DateTime get now => widget.now;
+//
+//   DateTime get selectedDate => widget.selectedDate;
+//
+//   late PageController _pageController;
+//
+//   @override
+//   void initState() {
+//     super.initState();
+//     _currentPageDate = selectedDate;
+//     _slectedDate = selectedDate;
+//     _pageController = PageController(initialPage: initialPage);
+//   }
+//
+//   @override
+//   void didUpdateWidget(covariant WeekPage oldWidget) {
+//     super.didUpdateWidget(oldWidget);
+//
+//     if (widget.selectedDate != oldWidget.selectedDate) {
+//       setState(() {
+//         _currentPageDate = widget.selectedDate;
+//         _slectedDate = widget.selectedDate;
+//       });
+//
+//       // 计算要滚动到的页面索引
+//       int targetPageIndex = _calculateTargetPageIndex(widget.selectedDate);
+//
+//       // 使用 WidgetsBinding 以确保在构建完成后再跳转页面
+//       WidgetsBinding.instance.addPostFrameCallback((_) {
+//         // 检查目标页面索引是否在有效范围内
+//         Log.d("targetPageIndex:$targetPageIndex pageCounts.length:${pageCounts.length}");
+//         if (targetPageIndex >= 0 && targetPageIndex < pageCounts.length) {
+//           _pageController.jumpToPage(targetPageIndex);
+//         } else {
+//           //超过了索引就刷新数据源?
+//           Log.d("超过了索引就刷新数据源");
+//         }
+//       });
+//     }
+//   }
+//
+//   // 计算要滚动到的页面索引
+//   int _calculateTargetPageIndex(DateTime date) {
+//     // 获取当前周的第一天
+//     DateTime currentFirstDayOfWeek = firstDayOfWeek(now);
+//     // 获取选中日期的周的第一天
+//     DateTime targetFirstDayOfWeek = firstDayOfWeek(date);
+//
+//     // 计算当前日期与目标日期之间的天数差
+//     int differenceInDays = targetFirstDayOfWeek.difference(currentFirstDayOfWeek).inDays + 1;
+//
+//     // 计算目标页面索引
+//     // 每页14天
+//     int targetPageIndex = (differenceInDays / 14).floor(); // 用floor确保向下取整
+//
+//     // 确保目标索引在有效范围内
+//     // targetPageIndex = (targetPageIndex + pageCounts.length) % pageCounts.length;
+//
+//     Log.d("differenceInDays:$differenceInDays targetPageIndex:$targetPageIndex");
+//
+//     return targetPageIndex;
+//   }
+//
+//   @override
+//   Widget build(BuildContext context) {
+//     return Flexible(
+//       child: AnimatedSize(
+//         duration: const Duration(milliseconds: 250),
+//         curve: Curves.easeInOut,
+//         alignment: Alignment.topCenter,
+//         child: SizedBox(
+//           height: height,
+//           child: pageViewBuilder(),
+//         ),
+//       ),
+//     );
+//   }
+//
+//   //PageView的方式展示不同的星期,每周每一个Page
+//   Widget pageViewBuilder() {
+//     return PageView.builder(
+//       itemBuilder: (context, index) {
+//         final idx = _getIndex(index);
+//         return dayTable(idx);
+//       },
+//       onPageChanged: onPageChanged,
+//       controller: _pageController,
+//     );
+//   }
+//
+//   //两周的数据
+//   Widget dayTable(int index) {
+//     int at = pageCounts[index] - 1;
+//     final weekdays = get2Weekdays(now, at);
+//     return DayTableView(
+//       weekdays: weekdays,
+//       onSelect: (date) {
+//         setState(() {
+//           _slectedDate = date;
+//         });
+//         //主动点击之后回调
+//         widget.onChangedSelectedDate?.call(date);
+//       },
+//       selectedDate: _slectedDate,
+//       currentDate: now,
+//     );
+//   }
+//
+//   //是否需要切换页面的时候自动选中
+//   void changeSelectedDate(int value) {
+//     if (_pageState(value) == PageState.next) {
+//       if (widget.isAutoSelect) {
+//         _slectedDate = addDay(selectedDate, 14);
+//         widget.onChangedSelectedDate?.call(_slectedDate);
+//       }
+//     } else {
+//       if (widget.isAutoSelect) {
+//         _slectedDate = subtractDay(selectedDate, 14);
+//         widget.onChangedSelectedDate?.call(_slectedDate);
+//       }
+//     }
+//   }
+//
+//   //当切换页面的时候更新当前页面数据,返回当前页面第一条数据的日期
+//   void updateCurrentPageDate(int value) {
+//     final first = firstDayOfWeek(_currentPageDate);
+//
+//     if (_pageState(value) == PageState.next) {
+//       _currentPageDate = addDay(first, 14);
+//       widget.onChangedPage?.call(_currentPageDate, PageState.next);
+//     } else {
+//       _currentPageDate = subtractDay(first, 14);
+//       widget.onChangedPage?.call(_currentPageDate, PageState.previous);
+//     }
+//   }
+//
+//   void onPageChanged(int value) {
+//     changeSelectedDate(value);
+//     updateCurrentPageDate(value);
+//
+//     int currentIndex = _getIndex(value);
+//     int leftIndex = (currentIndex - 1 < 0) ? pageCounts.length - 1 : currentIndex - 1;
+//     int rightIndex = (currentIndex + 1 > pageCounts.length - 1) ? 0 : currentIndex + 1;
+//
+//     pageCounts[leftIndex] = pageCounts[currentIndex] - 1;
+//     pageCounts[rightIndex] = pageCounts[currentIndex] + 1;
+//
+//     currentPage = pageCounts[currentIndex];
+//   }
+//
+//   int _getIndex(int idx) {
+//     return (idx + 1) % pageCounts.length;
+//   }
+//
+//   PageState _pageState(int idx) {
+//     final prePage = currentPage;
+//     final current = pageCounts[_getIndex(idx)];
+//     return (prePage < current) ? PageState.next : PageState.previous;
+//   }
+// }

+ 38 - 28
packages/cs_widgets/lib/shatter/weekly_calendar/weekly_calendar.dart

@@ -1,25 +1,20 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:intl/date_symbol_data_local.dart';
 import 'package:intl/date_symbol_data_local.dart';
-import 'package:widgets/shatter/weekly_calendar/week_page.dart';
-
-import 'calendar_utils.dart' show getWeekdays;
+import 'package:shared/utils/log_utils.dart';
+import 'calendar_utils.dart';
 import 'day_of_week_view.dart';
 import 'day_of_week_view.dart';
+import 'day_table_view.dart';
 
 
 /// 总入口,整合顶部的Week控件与底部的Days的PageView控件
 /// 总入口,整合顶部的Week控件与底部的Days的PageView控件
 class WeeklyCalendar extends StatefulWidget {
 class WeeklyCalendar extends StatefulWidget {
   const WeeklyCalendar({
   const WeeklyCalendar({
     super.key,
     super.key,
-    this.isAutoSelect = false,
     this.onChangedSelectedDate,
     this.onChangedSelectedDate,
-    this.onChangedPage,
     this.selectedDate,
     this.selectedDate,
   });
   });
 
 
-
-  final DateTime? selectedDate;
-  final bool isAutoSelect;
-  final Function(DateTime)? onChangedSelectedDate;
-  final Function(DateTime date, PageState state)? onChangedPage;
+  final DateTime? selectedDate; //当前选中的日期
+  final Function(DateTime)? onChangedSelectedDate; //选择日期的回调
 
 
   @override
   @override
   State<StatefulWidget> createState() => _WeeklyCalendarState();
   State<StatefulWidget> createState() => _WeeklyCalendarState();
@@ -27,15 +22,35 @@ class WeeklyCalendar extends StatefulWidget {
 
 
 class _WeeklyCalendarState extends State<WeeklyCalendar> {
 class _WeeklyCalendarState extends State<WeeklyCalendar> {
   final DateTime now = DateTime.now();
   final DateTime now = DateTime.now();
-  late DateTime selectedDate;
-  DateTime currentPageDate = DateTime.now();
-
+  DateTime? selectedDate;
+  late List<DateTime> currentDateList;
 
 
   @override
   @override
   void initState() {
   void initState() {
-    initializeDateFormatting("en");  //日期国际化指定
+    initializeDateFormatting("en"); //日期国际化指定
     super.initState();
     super.initState();
-    selectedDate = widget.selectedDate ?? DateTime.now();
+
+    currentDateList = get2Weekdays(now, 0); //双周的数据
+    selectedDate = widget.selectedDate ?? now; //默认选中的数据
+  }
+
+  @override
+  void didUpdateWidget(covariant WeeklyCalendar oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    if (widget.selectedDate != oldWidget.selectedDate) {
+      //查看当前页面Date数据是否包含选中的 selectedDate
+      bool hasSelected = hasSelectedDate(currentDateList, widget.selectedDate ?? now);
+
+      setState(() {
+        selectedDate = widget.selectedDate;
+
+        if (!hasSelected) {
+          //如果不包含,需要更换数据源
+          Log.d("选中日期不在当前页面,需要更换数据源");
+          currentDateList = get2Weekdays(widget.selectedDate ?? now, 0);
+        }
+      });
+    }
   }
   }
 
 
   @override
   @override
@@ -48,24 +63,19 @@ class _WeeklyCalendarState extends State<WeeklyCalendar> {
 
 
         const SizedBox(height: 12),
         const SizedBox(height: 12),
 
 
-        //底部是每个星期的Days的PageView布局
-        WeekPage(
-          selectedDate: selectedDate,  //默认选中的日期,如果没有填写默认是今天
-          now: now,                    //今天的日期
-          isAutoSelect: widget.isAutoSelect,  //翻页是否自动选中
-          onChangedPage: (date, state) {
-            setState(() {
-              currentPageDate = date;
-            });
-            widget.onChangedPage?.call(date, state);
-          },
-          onChangedSelectedDate: (date) {
+        //底部是当前二周的数据
+        DayTableView(
+          weekdays: currentDateList,
+          onSelect: (date) {
             setState(() {
             setState(() {
               selectedDate = date;
               selectedDate = date;
             });
             });
+            //主动点击之后回调
             widget.onChangedSelectedDate?.call(date);
             widget.onChangedSelectedDate?.call(date);
           },
           },
-        ),
+          selectedDate: selectedDate ?? now,
+          currentDate: now,
+        )
       ],
       ],
     );
     );
   }
   }