Ver código fonte

payment首页完成

liukai 3 dias atrás
pai
commit
690ac0edb5
28 arquivos alterados com 1629 adições e 148 exclusões
  1. 1 1
      packages/cpt_facility/lib/modules/facility/active/item_facility_active.dart
  2. 1 1
      packages/cpt_facility/lib/modules/facility/history/item_facility_history.dart
  3. 40 3
      packages/cpt_payment/lib/modules/payment/condo/active/condo_active_screen.dart
  4. 31 0
      packages/cpt_payment/lib/modules/payment/condo/active/condo_active_state.dart
  5. 130 0
      packages/cpt_payment/lib/modules/payment/condo/active/condo_active_view_model.dart
  6. 27 0
      packages/cpt_payment/lib/modules/payment/condo/active/condo_active_view_model.g.dart
  7. 135 0
      packages/cpt_payment/lib/modules/payment/condo/active/item_condo_active.dart
  8. 0 81
      packages/cpt_payment/lib/modules/payment/condo/condo_screen.dart
  9. 38 4
      packages/cpt_payment/lib/modules/payment/condo/history/condo_history_screen.dart
  10. 31 0
      packages/cpt_payment/lib/modules/payment/condo/history/condo_history_state.dart
  11. 130 0
      packages/cpt_payment/lib/modules/payment/condo/history/condo_history_view_model.dart
  12. 27 0
      packages/cpt_payment/lib/modules/payment/condo/history/condo_history_view_model.g.dart
  13. 136 0
      packages/cpt_payment/lib/modules/payment/condo/history/item_condo_active.dart
  14. 146 0
      packages/cpt_payment/lib/modules/payment/condo/history/item_condo_history.dart
  15. 39 3
      packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_screen.dart
  16. 31 0
      packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_state.dart
  17. 130 0
      packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_view_model.dart
  18. 27 0
      packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_view_model.g.dart
  19. 56 0
      packages/cpt_payment/lib/modules/payment/condo/payment/item_condo_payment.dart
  20. 0 1
      packages/cpt_payment/lib/modules/payment/info/info_screen.dart
  21. 86 0
      packages/cpt_payment/lib/modules/payment/manage/item_manage.dart
  22. 71 4
      packages/cpt_payment/lib/modules/payment/manage/manage_screen.dart
  23. 31 0
      packages/cpt_payment/lib/modules/payment/manage/manage_state.dart
  24. 169 0
      packages/cpt_payment/lib/modules/payment/manage/manage_view_model.dart
  25. 26 0
      packages/cpt_payment/lib/modules/payment/manage/manage_view_model.g.dart
  26. 87 24
      packages/cpt_payment/lib/modules/payment/payment_page.dart
  27. 3 6
      packages/cpt_payment/lib/router/page/payment_page_router.dart
  28. 0 20
      packages/cpt_payment/lib/router/page/payment_page_router.gr.dart

+ 1 - 1
packages/cpt_facility/lib/modules/facility/active/item_facility_active.dart

@@ -20,7 +20,7 @@ class FacilityActiveItem extends StatelessWidget {
     return Container(
       width: double.infinity,
       margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
-      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 25),
+      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 23),
       decoration: BoxDecoration(
         color: context.appColors.whiteBG,
         borderRadius: BorderRadius.circular(6.0), // 圆角

+ 1 - 1
packages/cpt_facility/lib/modules/facility/history/item_facility_history.dart

@@ -20,7 +20,7 @@ class FacilityHistoryItem extends StatelessWidget {
     return Container(
       width: double.infinity,
       margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
-      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 25),
+      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 23),
       decoration: BoxDecoration(
         color: context.appColors.whiteBG,
         borderRadius: BorderRadius.circular(6.0), // 圆角

+ 40 - 3
packages/cpt_payment/lib/modules/payment/condo/active/condo_active_screen.dart

@@ -7,14 +7,51 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import 'condo_active_view_model.dart';
+import 'item_condo_active.dart';
+
 @RoutePage()
 class CondoActiveScreen extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(condoActiveViewModelProvider.notifier);
+    final state = ref.watch(condoActiveViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Container(
-      child: Center(
-        child: Text("CondoActiveScreen"),
-      ),
+      padding: const EdgeInsets.only(top: 60),
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return CondoActiveItem(index: index, item: state.datas[index]).onTap(() {
+
+                    });
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
     );
   }
 }

+ 31 - 0
packages/cpt_payment/lib/modules/payment/condo/active/condo_active_state.dart

@@ -0,0 +1,31 @@
+import 'package:widgets/load_state_layout.dart';
+
+class CondoActiveState {
+
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  List<String> datas; //页面列表数据
+
+  // ===================================  Begin  ↓  ===================================
+
+  CondoActiveState({
+    this.loadingState = LoadState.State_Loading,
+    this.errorMessage,
+    required this.datas,
+  });
+
+  CondoActiveState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    bool? needShowPlaceholder,
+    List<String>? datas,
+  }) {
+    return CondoActiveState(
+      errorMessage: errorMessage ?? this.errorMessage,
+      loadingState: loadingState ?? this.loadingState,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 130 - 0
packages/cpt_payment/lib/modules/payment/condo/active/condo_active_view_model.dart

@@ -0,0 +1,130 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'condo_active_state.dart';
+
+part 'condo_active_view_model.g.dart';
+
+@riverpod
+class CondoActiveViewModel extends _$CondoActiveViewModel {
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
+
+  @override
+  CondoActiveState build() {
+    return CondoActiveState(datas: []);
+  }
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchList();
+  }
+
+  /// 获取服务器数据
+  Future fetchList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    // 获取 Applied 列表
+    // var listResult = await _jobRepository.fetchJobAppliedList(
+    //   state.jobId,
+    //   state.selectedStatusId,
+    //   state.keyword,
+    //   curPage: _curPage,
+    //   cancelToken: cancelToken,
+    // );
+    //
+    // // 处理数据
+    // if (listResult.isSuccess) {
+    //   handleList(listResult.data?.rows);
+    // } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    // }
+
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
+
+    if (_curPage == 1) {
+      //刷新的方式
+      state = state.copyWith(datas: list);
+      refreshController.finishRefresh();
+
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      //加载更多
+      final allList = state.datas;
+      allList.addAll(list);
+      state.datas.addAll(list);
+
+      refreshController.finishLoad();
+
+      state = state.copyWith(datas: allList);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+// 处理数据与展示的逻辑
+// void handleList(List<JobAppliedListSGRows>? list) {
+//   if (list != null && list.isNotEmpty) {
+//     //有数据,判断是刷新还是加载更多的数据
+//     if (_curPage == 1) {
+//       //刷新的方式
+//       state.datas.clear();
+//       state.datas.addAll(list);
+//       refreshController.finishRefresh();
+//
+//       //更新展示的状态
+//       changeLoadingState(LoadState.State_Success);
+//     } else {
+//       //加载更多
+//       state.datas.addAll(list);
+//       refreshController.finishLoad();
+//       update();
+//     }
+//   } else {
+//     if (_curPage == 1) {
+//       //展示无数据的布局
+//       state.datas.clear();
+//       changeLoadingState(LoadState.State_Empty);
+//       refreshController.finishRefresh();
+//     } else {
+//       //展示加载完成,没有更多数据了
+//       refreshController.finishLoad(IndicatorResult.noMore);
+//     }
+//   }
+// }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment/condo/active/condo_active_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'condo_active_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$condoActiveViewModelHash() =>
+    r'd77976d1c081c1aabfafe5895b04bc202ec0beb2';
+
+/// See also [CondoActiveViewModel].
+@ProviderFor(CondoActiveViewModel)
+final condoActiveViewModelProvider = AutoDisposeNotifierProvider<
+    CondoActiveViewModel, CondoActiveState>.internal(
+  CondoActiveViewModel.new,
+  name: r'condoActiveViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$condoActiveViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$CondoActiveViewModel = AutoDisposeNotifier<CondoActiveState>;
+// 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

+ 135 - 0
packages/cpt_payment/lib/modules/payment/condo/active/item_condo_active.dart

@@ -0,0 +1,135 @@
+
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  Condo的Active的Item
+class CondoActiveItem extends StatelessWidget {
+  final int index;
+  final String item;
+
+  const CondoActiveItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 23),
+      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: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //设施
+              MyTextView(
+                "Lift Padding",
+                fontSize: 16,
+                maxLines: 3,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+
+              //预订人
+              MyTextView(
+                S.current.booked_by_someone("Wu Bing Bing"),
+                fontSize: 14,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //日期
+              MyTextView(
+                "Tue,24 Oct 2023",
+                fontSize: 14,
+                marginTop: 16,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //时间
+              MyTextView(
+                "05:00 PM-10:00 PM",
+                fontSize: 14,
+                marginBottom: 7,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //标签
+              Row(
+                children: [
+                  MyTextView(
+                    "Fee Paid",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  ),
+                  MyTextView(
+                    "Deposit",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  )
+                ],
+              )
+            ],
+          ).expanded(),
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment:MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //查看按钮
+              MyTextView(
+                S.current.view,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                cornerRadius: 7,
+                paddingTop: 9,
+                paddingBottom: 9,
+                textAlign: TextAlign.center,
+                boxWidth: 60,
+              )
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

+ 0 - 81
packages/cpt_payment/lib/modules/payment/condo/condo_screen.dart

@@ -1,81 +0,0 @@
-import 'package:auto_route/auto_route.dart';
-import 'package:cs_resources/generated/l10n.dart';
-import 'package:cs_resources/theme/app_colors_theme.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_hooks/flutter_hooks.dart';
-import 'package:hooks_riverpod/hooks_riverpod.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_text_view.dart';
-import 'package:widgets/widget_export.dart';
-
-import '../../../router/page/payment_page_router.dart';
-
-@RoutePage()
-class CondoScreen extends HookConsumerWidget {
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return AutoTabsRouter.pageView(
-      physics: const NeverScrollableScrollPhysics(),
-      routes: const [
-        CondoPaymentPageRoute(),
-        CondoActivePageRoute(),
-        CondoHistoryPageRoute(),
-      ],
-      builder: (context, child, pageController) {
-        final tabsRouter = AutoTabsRouter.of(context);
-
-        return Column(
-          children: [
-            Row(
-              mainAxisAlignment: MainAxisAlignment.spaceAround,
-              children: [
-                _buildTab(
-                  context,
-                  S.current.payment,
-                  tabsRouter.activeIndex == 0,
-                ).onTap(() {
-                  tabsRouter.setActiveIndex(0);
-                }),
-                _buildTab(
-                  context,
-                  S.current.facility_active,
-                  tabsRouter.activeIndex == 1,
-                ).onTap(() {
-                  tabsRouter.setActiveIndex(1);
-                }),
-                _buildTab(
-                  context,
-                  S.current.history,
-                  tabsRouter.activeIndex == 2,
-                ).onTap(() {
-                  tabsRouter.setActiveIndex(2);
-                }),
-              ],
-            ).marginOnly(top: 14, bottom: 17),
-            Expanded(
-              child: child,
-            ),
-          ],
-        );
-      },
-    );
-  }
-
-  //顶部的Tab布局
-  Widget _buildTab(BuildContext context, String title, bool isSelected) {
-    return MyTextView(
-      title,
-      fontSize: 16,
-      isFontMedium: true,
-      textColor: isSelected ? Colors.white : context.appColors.tabTextUnSelectedDefault,
-      backgroundColor: isSelected ? context.appColors.btnBgDefault : Colors.transparent,
-      cornerRadius: 16.5,
-      paddingLeft: 20,
-      paddingRight: 20,
-      paddingTop: 8,
-      paddingBottom: 8,
-    );
-  }
-}

+ 38 - 4
packages/cpt_payment/lib/modules/payment/condo/history/condo_history_screen.dart

@@ -2,19 +2,53 @@ import 'package:auto_route/auto_route.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.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/widget_export.dart';
 
+import 'condo_history_view_model.dart';
+import 'item_condo_history.dart';
+
 @RoutePage()
 class CondoHistoryScreen extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(condoHistoryViewModelProvider.notifier);
+    final state = ref.watch(condoHistoryViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Container(
-      child: Center(
-        child: Text("CondoHistoryScreen"),
-      ),
+      padding: const EdgeInsets.only(top: 60),
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+              (context, index) {
+                return CondoHistoryItem(index: index, item: state.datas[index]).onTap(() {});
+              },
+              childCount: state.datas.length,
+            ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
     );
   }
 }

+ 31 - 0
packages/cpt_payment/lib/modules/payment/condo/history/condo_history_state.dart

@@ -0,0 +1,31 @@
+import 'package:widgets/load_state_layout.dart';
+
+class CondoHistoryState {
+
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  List<String> datas; //页面列表数据
+
+  // ===================================  Begin  ↓  ===================================
+
+  CondoHistoryState({
+    this.loadingState = LoadState.State_Loading,
+    this.errorMessage,
+    required this.datas,
+  });
+
+  CondoHistoryState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    bool? needShowPlaceholder,
+    List<String>? datas,
+  }) {
+    return CondoHistoryState(
+      errorMessage: errorMessage ?? this.errorMessage,
+      loadingState: loadingState ?? this.loadingState,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 130 - 0
packages/cpt_payment/lib/modules/payment/condo/history/condo_history_view_model.dart

@@ -0,0 +1,130 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'condo_history_state.dart';
+
+part 'condo_history_view_model.g.dart';
+
+@riverpod
+class CondoHistoryViewModel extends _$CondoHistoryViewModel {
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
+
+  @override
+  CondoHistoryState build() {
+    return CondoHistoryState(datas: []);
+  }
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchList();
+  }
+
+  /// 获取服务器数据
+  Future fetchList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    // 获取 Applied 列表
+    // var listResult = await _jobRepository.fetchJobAppliedList(
+    //   state.jobId,
+    //   state.selectedStatusId,
+    //   state.keyword,
+    //   curPage: _curPage,
+    //   cancelToken: cancelToken,
+    // );
+    //
+    // // 处理数据
+    // if (listResult.isSuccess) {
+    //   handleList(listResult.data?.rows);
+    // } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    // }
+
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
+
+    if (_curPage == 1) {
+      //刷新的方式
+      state = state.copyWith(datas: list);
+      refreshController.finishRefresh();
+
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      //加载更多
+      final allList = state.datas;
+      allList.addAll(list);
+      state.datas.addAll(list);
+
+      refreshController.finishLoad();
+
+      state = state.copyWith(datas: allList);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+// 处理数据与展示的逻辑
+// void handleList(List<JobAppliedListSGRows>? list) {
+//   if (list != null && list.isNotEmpty) {
+//     //有数据,判断是刷新还是加载更多的数据
+//     if (_curPage == 1) {
+//       //刷新的方式
+//       state.datas.clear();
+//       state.datas.addAll(list);
+//       refreshController.finishRefresh();
+//
+//       //更新展示的状态
+//       changeLoadingState(LoadState.State_Success);
+//     } else {
+//       //加载更多
+//       state.datas.addAll(list);
+//       refreshController.finishLoad();
+//       update();
+//     }
+//   } else {
+//     if (_curPage == 1) {
+//       //展示无数据的布局
+//       state.datas.clear();
+//       changeLoadingState(LoadState.State_Empty);
+//       refreshController.finishRefresh();
+//     } else {
+//       //展示加载完成,没有更多数据了
+//       refreshController.finishLoad(IndicatorResult.noMore);
+//     }
+//   }
+// }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment/condo/history/condo_history_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'condo_history_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$condoHistoryViewModelHash() =>
+    r'7ab487088e11c7906117e903b6fcda88f4b5558c';
+
+/// See also [CondoHistoryViewModel].
+@ProviderFor(CondoHistoryViewModel)
+final condoHistoryViewModelProvider = AutoDisposeNotifierProvider<
+    CondoHistoryViewModel, CondoHistoryState>.internal(
+  CondoHistoryViewModel.new,
+  name: r'condoHistoryViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$condoHistoryViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$CondoHistoryViewModel = AutoDisposeNotifier<CondoHistoryState>;
+// 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

+ 136 - 0
packages/cpt_payment/lib/modules/payment/condo/history/item_condo_active.dart

@@ -0,0 +1,136 @@
+
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  Condo的Active的Item
+class CondoActiveItem extends StatelessWidget {
+  final int index;
+  final String item;
+
+  const CondoActiveItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 25),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteBG,
+        borderRadius: BorderRadius.circular(6.0), // 圆角
+      ),
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //设施
+              MyTextView(
+                "Lift Padding",
+                fontSize: 16,
+                maxLines: 3,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+
+              //分类
+              MyTextView(
+                "Booked by YONGLIANG WU",
+                fontSize: 14,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //预订人
+              MyTextView(
+                S.current.booked_by_someone("Wu Bing Bing"),
+                fontSize: 14,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //日期
+              MyTextView(
+                "Tue,24 Oct 2023",
+                fontSize: 14,
+                marginTop: 16,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //时间
+              MyTextView(
+                "05:00 PM-10:00 PM",
+                fontSize: 14,
+                marginBottom: 7,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //标签
+              Row(
+                children: [
+                  MyTextView(
+                    "Fee Paid",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  ),
+                  MyTextView(
+                    "Deposit",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  )
+                ],
+              )
+            ],
+          ).expanded(),
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment:MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //查看按钮
+              MyTextView(
+                S.current.view,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                cornerRadius: 7,
+                paddingTop: 9,
+                paddingBottom: 9,
+                textAlign: TextAlign.center,
+                boxWidth: 60,
+              )
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

+ 146 - 0
packages/cpt_payment/lib/modules/payment/condo/history/item_condo_history.dart

@@ -0,0 +1,146 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  Condo的History的Item
+class CondoHistoryItem extends StatelessWidget {
+  final int index;
+  final String item;
+
+  const CondoHistoryItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.only(left: 20, right: 15, top: 18, bottom: 23),
+      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: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //设施
+              MyTextView(
+                "Kids party room",
+                fontSize: 16,
+                maxLines: 3,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+
+              //预订人
+              MyTextView(
+                S.current.booked_by_someone("Wu Bing Bing"),
+                fontSize: 14,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //日期
+              MyTextView(
+                "Tue,24 Oct 2023",
+                fontSize: 14,
+                marginTop: 16,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //时间
+              MyTextView(
+                "05:00 PM-10:00 PM",
+                fontSize: 14,
+                marginBottom: 7,
+                marginTop: 3,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              //标签
+              Row(
+                children: [
+                  MyTextView(
+                    "Fee Paid",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  ),
+                  MyTextView(
+                    "Deposit Released",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 13,
+                    isFontRegular: true,
+                    backgroundColor: context.appColors.lightPurpleBg,
+                    cornerRadius: 3,
+                    paddingLeft: 7,
+                    marginRight: 6,
+                    paddingRight: 7,
+                    paddingTop: 3,
+                    paddingBottom: 3,
+                  )
+                ],
+              )
+            ],
+          ).expanded(),
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment:MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //查看按钮
+              MyTextView(
+                S.current.view,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                cornerRadius: 7,
+                paddingTop: 9,
+                paddingBottom: 9,
+                textAlign: TextAlign.center,
+                boxWidth: 60,
+              ),
+
+              MyTextView(
+                S.current.delete,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.orangeBG,
+                cornerRadius: 7,
+                paddingTop: 9,
+                marginTop: 15,
+                paddingBottom: 9,
+                textAlign: TextAlign.center,
+                boxWidth: 60,
+              )
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

+ 39 - 3
packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_screen.dart

@@ -6,15 +6,51 @@ import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
+import 'condo_payment_view_model.dart';
+import 'item_condo_payment.dart';
 
 @RoutePage()
 class CondoPaymentScreen extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(condoPaymentViewModelProvider.notifier);
+    final state = ref.watch(condoPaymentViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Container(
-      child: Center(
-        child: Text("CondoPaymentScreen"),
-      ),
+      padding: const EdgeInsets.only(top: 60),
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return CondoPaymentItem(index: index, item: state.datas[index]).onTap(() {
+
+                    });
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
     );
   }
 }

+ 31 - 0
packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_state.dart

@@ -0,0 +1,31 @@
+import 'package:widgets/load_state_layout.dart';
+
+class CondoPaymentState {
+
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  List<String> datas; //页面列表数据
+
+  // ===================================  Begin  ↓  ===================================
+
+  CondoPaymentState({
+    this.loadingState = LoadState.State_Loading,
+    this.errorMessage,
+    required this.datas,
+  });
+
+  CondoPaymentState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    bool? needShowPlaceholder,
+    List<String>? datas,
+  }) {
+    return CondoPaymentState(
+      errorMessage: errorMessage ?? this.errorMessage,
+      loadingState: loadingState ?? this.loadingState,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 130 - 0
packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_view_model.dart

@@ -0,0 +1,130 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'condo_payment_state.dart';
+
+part 'condo_payment_view_model.g.dart';
+
+@riverpod
+class CondoPaymentViewModel extends _$CondoPaymentViewModel{
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
+
+  @override
+  CondoPaymentState build() {
+    return CondoPaymentState(datas: []);
+  }
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchList();
+  }
+
+  /// 获取服务器数据
+  Future fetchList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    // 获取 Applied 列表
+    // var listResult = await _jobRepository.fetchJobAppliedList(
+    //   state.jobId,
+    //   state.selectedStatusId,
+    //   state.keyword,
+    //   curPage: _curPage,
+    //   cancelToken: cancelToken,
+    // );
+    //
+    // // 处理数据
+    // if (listResult.isSuccess) {
+    //   handleList(listResult.data?.rows);
+    // } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    // }
+
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
+
+    if (_curPage == 1) {
+      //刷新的方式
+      state = state.copyWith(datas: list);
+      refreshController.finishRefresh();
+
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      //加载更多
+      final allList = state.datas;
+      allList.addAll(list);
+      state.datas.addAll(list);
+
+      refreshController.finishLoad();
+
+      state = state.copyWith(datas: allList);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+// 处理数据与展示的逻辑
+// void handleList(List<JobAppliedListSGRows>? list) {
+//   if (list != null && list.isNotEmpty) {
+//     //有数据,判断是刷新还是加载更多的数据
+//     if (_curPage == 1) {
+//       //刷新的方式
+//       state.datas.clear();
+//       state.datas.addAll(list);
+//       refreshController.finishRefresh();
+//
+//       //更新展示的状态
+//       changeLoadingState(LoadState.State_Success);
+//     } else {
+//       //加载更多
+//       state.datas.addAll(list);
+//       refreshController.finishLoad();
+//       update();
+//     }
+//   } else {
+//     if (_curPage == 1) {
+//       //展示无数据的布局
+//       state.datas.clear();
+//       changeLoadingState(LoadState.State_Empty);
+//       refreshController.finishRefresh();
+//     } else {
+//       //展示加载完成,没有更多数据了
+//       refreshController.finishLoad(IndicatorResult.noMore);
+//     }
+//   }
+// }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'condo_payment_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$condoPaymentViewModelHash() =>
+    r'44e4b8307ca06e13e1dec0e95580b55ae4027a09';
+
+/// See also [CondoPaymentViewModel].
+@ProviderFor(CondoPaymentViewModel)
+final condoPaymentViewModelProvider = AutoDisposeNotifierProvider<
+    CondoPaymentViewModel, CondoPaymentState>.internal(
+  CondoPaymentViewModel.new,
+  name: r'condoPaymentViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$condoPaymentViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$CondoPaymentViewModel = AutoDisposeNotifier<CondoPaymentState>;
+// 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

+ 56 - 0
packages/cpt_payment/lib/modules/payment/condo/payment/item_condo_payment.dart

@@ -0,0 +1,56 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+/// Condo Active 的 Item 布局
+class CondoPaymentItem extends StatelessWidget {
+  final int index;
+  final String item;
+
+  const CondoPaymentItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      height: 80,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.symmetric(horizontal: 20),
+      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: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          MyLoadImage(
+            "https://img0.baidu.com/it/u=2679587808,2501833998&fm=253&fmt=auto&app=120&f=JPEG?w=372&h=400",
+            height: 33,
+          ),
+
+          MyTextView(
+            "Function Room",
+            marginLeft: 17,
+            fontSize: 16,
+            textColor: context.appColors.textBlack,
+            isFontMedium: true,
+          ).expanded(),
+        ],
+      ),
+    );
+  }
+}

+ 0 - 1
packages/cpt_payment/lib/modules/payment/info/info_screen.dart

@@ -1,5 +1,4 @@
 import 'package:auto_route/auto_route.dart';
-import 'package:cpt_payment/modules/payment/condo/condo_screen.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';

+ 86 - 0
packages/cpt_payment/lib/modules/payment/manage/item_manage.dart

@@ -0,0 +1,86 @@
+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:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  Condo的Manage的Item
+class ManageItem extends StatelessWidget {
+  final int index;
+  final bool item;
+  final VoidCallback deleteAction;
+
+  const ManageItem({
+    required this.index,
+    required this.item,
+    required this.deleteAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      margin: const EdgeInsets.only(top: 1),
+      color: context.appColors.whiteBG,
+      width: double.infinity,
+      padding: const EdgeInsets.only(left: 20, right: 23, top: 20, bottom: 20),
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          //选中
+          MyAssetImage(
+            item ? Assets.baseServiceRadioChecked : Assets.baseServiceRadioUncheck,
+            width: 25,
+            height: 25,
+          ),
+
+          MyAssetImage(
+            Assets.facilityAddCardMaster,
+            height: 38,
+          ).marginOnly(left: 9, right: 9),
+
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              MyTextView(
+                "Wu Bing Bing's Card",
+                textColor: context.appColors.textBlack,
+                fontSize: 13.5,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                "Ending 9423",
+                textColor: context.appColors.textBlack,
+                fontSize: 13.5,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                item ? S.current.primary_card : S.current.set_primary_card,
+                textColor: context.appColors.textPrimary,
+                fontSize: 12,
+                marginTop: 3,
+                fontWeight: FontWeight.w600,
+              ),
+            ],
+          ).expanded(),
+
+          MyTextView(
+            S.current.delete,
+            textColor: Colors.white,
+            backgroundColor: context.appColors.orangeBG,
+            cornerRadius: 7,
+            marginLeft: 9,
+            paddingTop: 9,
+            onClick: deleteAction,
+            marginTop: 15,
+            paddingBottom: 9,
+            textAlign: TextAlign.center,
+            boxWidth: 60,
+          )
+        ],
+      ),
+    );
+  }
+}

+ 71 - 4
packages/cpt_payment/lib/modules/payment/manage/manage_screen.dart

@@ -1,20 +1,87 @@
 import 'package:auto_route/auto_route.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.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_text_view.dart';
 import 'package:widgets/widget_export.dart';
 
+import 'item_manage.dart';
+import 'manage_view_model.dart';
+
 @RoutePage()
 class ManageScreen extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Container(
-      child: Center(
-        child: Text("Manage Screen"),
-      ),
+    final viewModel = ref.read(manageViewModelProvider.notifier);
+    final state = ref.watch(manageViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return SizedBox(
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            //添加新卡
+            SliverToBoxAdapter(
+              child: MyTextView(
+                S.current.add_new_card,
+                fontSize: 16,
+                textAlign: TextAlign.center,
+                marginLeft: 22.5,
+                marginTop: 14,
+                marginBottom: 15,
+                marginRight: 22.5,
+                cornerRadius: 5,
+                paddingTop: 12,
+                paddingBottom: 12,
+                onClick: viewModel.gotoAddCardPage,
+                borderWidth: 1,
+                borderColor: context.appColors.textPrimary,
+                isFontMedium: true,
+                textColor: context.appColors.textPrimary,
+              ),
+            ),
+
+            //列表
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+              (context, index) {
+                return ManageItem(
+                  index: index,
+                  item: state.datas[index],
+                  deleteAction: () {
+                    viewModel.showDeleteDialog(index);
+                  },
+                ).onTap(() {
+                  viewModel.setAsPrimary(index);
+                });
+              },
+              childCount: state.datas.length,
+            ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
     );
   }
 }

+ 31 - 0
packages/cpt_payment/lib/modules/payment/manage/manage_state.dart

@@ -0,0 +1,31 @@
+import 'package:widgets/load_state_layout.dart';
+
+class ManageState {
+
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  List<bool> datas; //页面列表数据
+
+  // ===================================  Begin  ↓  ===================================
+
+  ManageState({
+    this.loadingState = LoadState.State_Loading,
+    this.errorMessage,
+    required this.datas,
+  });
+
+  ManageState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    bool? needShowPlaceholder,
+    List<bool>? datas,
+  }) {
+    return ManageState(
+      errorMessage: errorMessage ?? this.errorMessage,
+      loadingState: loadingState ?? this.loadingState,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 169 - 0
packages/cpt_payment/lib/modules/payment/manage/manage_view_model.dart

@@ -0,0 +1,169 @@
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/dialog/app_default_dialog.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'manage_state.dart';
+
+part 'manage_view_model.g.dart';
+
+@riverpod
+class ManageViewModel extends _$ManageViewModel {
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
+  );
+
+  @override
+  ManageState build() {
+    return ManageState(datas: []);
+  }
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchList();
+  }
+
+  /// 获取服务器数据
+  Future fetchList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    // 获取 Applied 列表
+    // var listResult = await _jobRepository.fetchJobAppliedList(
+    //   state.jobId,
+    //   state.selectedStatusId,
+    //   state.keyword,
+    //   curPage: _curPage,
+    //   cancelToken: cancelToken,
+    // );
+    //
+    // // 处理数据
+    // if (listResult.isSuccess) {
+    //   handleList(listResult.data?.rows);
+    // } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    // }
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    final List<bool> list = [true, false, false, false];
+
+    if (_curPage == 1) {
+      //刷新的方式
+      state = state.copyWith(datas: list);
+      refreshController.finishRefresh();
+
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      //加载更多
+      final allList = state.datas;
+      allList.addAll(list);
+      state.datas.addAll(list);
+
+      refreshController.finishLoad();
+
+      state = state.copyWith(datas: allList);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+// 处理数据与展示的逻辑
+// void handleList(List<JobAppliedListSGRows>? list) {
+//   if (list != null && list.isNotEmpty) {
+//     //有数据,判断是刷新还是加载更多的数据
+//     if (_curPage == 1) {
+//       //刷新的方式
+//       state.datas.clear();
+//       state.datas.addAll(list);
+//       refreshController.finishRefresh();
+//
+//       //更新展示的状态
+//       changeLoadingState(LoadState.State_Success);
+//     } else {
+//       //加载更多
+//       state.datas.addAll(list);
+//       refreshController.finishLoad();
+//       update();
+//     }
+//   } else {
+//     if (_curPage == 1) {
+//       //展示无数据的布局
+//       state.datas.clear();
+//       changeLoadingState(LoadState.State_Empty);
+//       refreshController.finishRefresh();
+//     } else {
+//       //展示加载完成,没有更多数据了
+//       refreshController.finishLoad(IndicatorResult.noMore);
+//     }
+//   }
+// }
+
+  //设置为主卡
+  void setAsPrimary(int index) {
+    bool isPrimary = state.datas[index];
+
+    if (!isPrimary) {
+      // 创建数据列表的副本
+      List<bool> newDataList = List.from(state.datas);
+
+      //先全部设置为 false
+      for (int i = 0; i < newDataList.length; i++) {
+        newDataList[i] = false;
+      }
+
+      //再把当前索引设置为 true
+      newDataList[index] = true;
+
+      state = state.copyWith(datas: newDataList);
+    }
+  }
+
+  // 删除提示弹窗
+  void showDeleteDialog(int index) {
+    DialogEngine.show(
+        widget: AppDefaultDialog(
+      message: "Are you sure you want to delete this Card?",
+      confirmAction: () {
+        ToastEngine.show("点击了确定");
+      },
+    ));
+  }
+
+  //去添加新卡的页面
+  void gotoAddCardPage() {
+
+  }
+
+}

+ 26 - 0
packages/cpt_payment/lib/modules/payment/manage/manage_view_model.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'manage_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$manageViewModelHash() => r'9e6b2c00e4ed57279830e8738a899e01543b4783';
+
+/// See also [ManageViewModel].
+@ProviderFor(ManageViewModel)
+final manageViewModelProvider =
+    AutoDisposeNotifierProvider<ManageViewModel, ManageState>.internal(
+  ManageViewModel.new,
+  name: r'manageViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$manageViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$ManageViewModel = AutoDisposeNotifier<ManageState>;
+// 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

+ 87 - 24
packages/cpt_payment/lib/modules/payment/payment_page.dart

@@ -6,8 +6,10 @@ import 'package:cs_resources/theme/theme_config.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/services.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.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/my_appbar.dart';
 import 'package:widgets/my_load_image.dart';
@@ -30,24 +32,34 @@ class PaymentPage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final viewModel = ref.read(paymentViewModelProvider.notifier);
+    final viewModel = ref.watch(paymentViewModelProvider.notifier);
+    int selectedInnerIndex = 1; // 1-3索引记录当前的值
 
     return Scaffold(
       appBar: MyAppBar.appBar(
         context,
-        S.current.facility,
+        S.current.payment,
         backgroundColor: context.appColors.whiteBG,
       ),
       backgroundColor: context.appColors.backgroundDark,
       body: AutoTabsRouter.pageView(
         routes: const [
           InfoPageRoute(),
-          CondoPageRoute(),
+          CondoPaymentPageRoute(),
+          CondoActivePageRoute(),
+          CondoHistoryPageRoute(),
           ManagePageRoute(),
         ],
         builder: (context, child, pageController) {
           final tabsRouter = AutoTabsRouter.of(context);
 
+          pageController.addListener(() {
+            //监听赋值内部的选中索引
+            if (tabsRouter.activeIndex >= 1 && tabsRouter.activeIndex <= 3) {
+              selectedInnerIndex = tabsRouter.activeIndex;
+            }
+          });
+
           return Column(
             children: [
               Container(
@@ -56,8 +68,7 @@ class PaymentPage extends HookConsumerWidget {
                 child: Row(
                   mainAxisAlignment: MainAxisAlignment.spaceAround,
                   children: [
-                    
-                    _buildCategory(
+                    _buildTopCategory(
                       context,
                       Assets.paymentInfoIcon,
                       34,
@@ -65,39 +76,75 @@ class PaymentPage extends HookConsumerWidget {
                       "Info",
                       tabsRouter.activeIndex == 0,
                     ).onTap(
-                          () {
+                      () {
                         tabsRouter.setActiveIndex(0);
                       },
                     ),
-                    _buildCategory(
+                    _buildTopCategory(
                       context,
                       Assets.paymentCondoIcon,
                       48,
                       43,
-                     "Condo",
-                      tabsRouter.activeIndex == 1,
+                      "Condo",
+                      tabsRouter.activeIndex == 1 || tabsRouter.activeIndex == 2 || tabsRouter.activeIndex == 3,
                     ).onTap(
-                          () {
-                        tabsRouter.setActiveIndex(1);
+                      () {
+                        tabsRouter.setActiveIndex(selectedInnerIndex);
                       },
                     ),
-                    _buildCategory(
+                    _buildTopCategory(
                       context,
                       Assets.paymentManageIcon,
                       52,
                       46.5,
                       "Manage",
-                      tabsRouter.activeIndex == 2,
+                      tabsRouter.activeIndex == 4,
                     ).onTap(
-                          () {
-                        tabsRouter.setActiveIndex(2);
+                      () {
+                        tabsRouter.setActiveIndex(4);
                       },
                     ),
                   ],
                 ),
               ),
               Expanded(
-                child: child,
+                child: Stack(
+                  children: [
+                    //真正页面
+                    child,
+
+                    //顶部的子Tab
+                    Visibility(
+                      visible: tabsRouter.activeIndex >= 1 && tabsRouter.activeIndex <= 3,
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceAround,
+                        children: [
+                          _buildInnerTab(
+                            context,
+                            S.current.payment,
+                            tabsRouter.activeIndex == 1,
+                          ).onTap(() {
+                            tabsRouter.setActiveIndex(1);
+                          }),
+                          _buildInnerTab(
+                            context,
+                            S.current.facility_active,
+                            tabsRouter.activeIndex == 2,
+                          ).onTap(() {
+                            tabsRouter.setActiveIndex(2);
+                          }),
+                          _buildInnerTab(
+                            context,
+                            S.current.history,
+                            tabsRouter.activeIndex == 3,
+                          ).onTap(() {
+                            tabsRouter.setActiveIndex(3);
+                          }),
+                        ],
+                      ).marginOnly(top: 14, bottom: 17),
+                    ),
+                  ],
+                ),
               ),
             ],
           );
@@ -107,7 +154,7 @@ class PaymentPage extends HookConsumerWidget {
   }
 
   //顶部的Tab布局
-  Widget _buildCategory(BuildContext context, String iconPath, double iconWidth, double iconHeight, String title, bool isSelected) {
+  Widget _buildTopCategory(BuildContext context, String iconPath, double iconWidth, double iconHeight, String title, bool isSelected) {
     return Column(
       mainAxisAlignment: MainAxisAlignment.center,
       crossAxisAlignment: CrossAxisAlignment.center,
@@ -120,13 +167,13 @@ class PaymentPage extends HookConsumerWidget {
             shape: BoxShape.circle, // 设置为圆形
             boxShadow: isSelected
                 ? [
-              BoxShadow(
-                color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
-                blurRadius: 5, // 设置模糊半径
-                spreadRadius: 0.05, // 控制阴影扩散
-                offset: const Offset(0, 4), // 设置阴影偏移量
-              ),
-            ]
+                    BoxShadow(
+                      color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
+                      blurRadius: 5, // 设置模糊半径
+                      spreadRadius: 0.05, // 控制阴影扩散
+                      offset: const Offset(0, 4), // 设置阴影偏移量
+                    ),
+                  ]
                 : [], // 未选中时无阴影,
           ),
           child: Center(
@@ -143,4 +190,20 @@ class PaymentPage extends HookConsumerWidget {
       ],
     );
   }
+
+  //内部的Tab布局
+  Widget _buildInnerTab(BuildContext context, String title, bool isSelected) {
+    return MyTextView(
+      title,
+      fontSize: 16,
+      isFontMedium: true,
+      textColor: isSelected ? Colors.white : context.appColors.tabTextUnSelectedDefault,
+      backgroundColor: isSelected ? context.appColors.btnBgDefault : Colors.transparent,
+      cornerRadius: 16.5,
+      paddingLeft: 20,
+      paddingRight: 20,
+      paddingTop: 8,
+      paddingBottom: 8,
+    );
+  }
 }

+ 3 - 6
packages/cpt_payment/lib/router/page/payment_page_router.dart

@@ -6,7 +6,6 @@ import 'package:router/path/router_path.dart';
 import '../../modules/payment/payment_page.dart';
 import '../../modules/payment/info/info_screen.dart';
 import '../../modules/payment/manage/manage_screen.dart';
-import '../../modules/payment/condo/condo_screen.dart';
 import '../../modules/payment/condo/active/condo_active_screen.dart';
 import '../../modules/payment/condo/history/condo_history_screen.dart';
 import '../../modules/payment/condo/payment/condo_payment_screen.dart';
@@ -26,11 +25,9 @@ class PaymentPageRouter extends _$PaymentPageRouter {
           transitionsBuilder: applySlideTransition,
           children: [
             AutoRoute(page: InfoPageRoute.page, path: 'info'),
-            AutoRoute(page: CondoPageRoute.page, path: 'condo', children: [
-              AutoRoute(page: CondoPaymentPageRoute.page, path: 'payment'),
-              AutoRoute(page: CondoActivePageRoute.page, path: 'active'),
-              AutoRoute(page: CondoHistoryPageRoute.page, path: 'history'),
-            ]),
+            AutoRoute(page: CondoPaymentPageRoute.page, path: 'payment'),
+            AutoRoute(page: CondoActivePageRoute.page, path: 'active'),
+            AutoRoute(page: CondoHistoryPageRoute.page, path: 'history'),
             AutoRoute(page: ManagePageRoute.page, path: 'manage'),
           ],
         ),

+ 0 - 20
packages/cpt_payment/lib/router/page/payment_page_router.gr.dart

@@ -33,12 +33,6 @@ abstract class _$PaymentPageRouter extends RootStackRouter {
         child: CondoPaymentScreen(),
       );
     },
-    CondoPageRoute.name: (routeData) {
-      return AutoRoutePage<dynamic>(
-        routeData: routeData,
-        child: CondoScreen(),
-      );
-    },
     InfoPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -103,20 +97,6 @@ class CondoPaymentPageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
-/// [CondoScreen]
-class CondoPageRoute extends PageRouteInfo<void> {
-  const CondoPageRoute({List<PageRouteInfo>? children})
-      : super(
-          CondoPageRoute.name,
-          initialChildren: children,
-        );
-
-  static const String name = 'CondoPageRoute';
-
-  static const PageInfo<void> page = PageInfo<void>(name);
-}
-
-/// generated route for
 /// [InfoScreen]
 class InfoPageRoute extends PageRouteInfo<void> {
   const InfoPageRoute({List<PageRouteInfo>? children})