5 Коммиты 74f02a9f2e ... 2ad8360ac7

Автор SHA1 Сообщение Дата
  liukai 2ad8360ac7 Merge remote-tracking branch 'origin/dev' into dev дней назад: 2
  liukai 192bc9adc1 路由跳转 дней назад: 2
  liukai 3db1dee2f2 payment 切换支付方式设置主卡,添加银行卡 дней назад: 2
  liukai 866e7f60e3 Merge remote-tracking branch 'origin/dev' into dev дней назад: 2
  liukai 9730f0f154 payment 支付信息,支付确认,支付成功 дней назад: 3
39 измененных файлов с 1530 добавлено и 12 удалено
  1. 5 2
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_page.dart
  2. 7 3
      packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.dart
  3. 222 0
      packages/cpt_payment/lib/modules/add_card/add_card_page.dart
  4. 48 0
      packages/cpt_payment/lib/modules/add_card/add_card_state.dart
  5. 76 0
      packages/cpt_payment/lib/modules/add_card/add_card_view_model.dart
  6. 26 0
      packages/cpt_payment/lib/modules/add_card/add_card_view_model.g.dart
  7. 128 0
      packages/cpt_payment/lib/modules/choose_card/choose_card_page.dart
  8. 32 0
      packages/cpt_payment/lib/modules/choose_card/choose_card_state.dart
  9. 168 0
      packages/cpt_payment/lib/modules/choose_card/choose_card_view_model.dart
  10. 27 0
      packages/cpt_payment/lib/modules/choose_card/choose_card_view_model.g.dart
  11. 3 1
      packages/cpt_payment/lib/modules/payment/condo/payment/condo_payment_screen.dart
  12. 2 1
      packages/cpt_payment/lib/modules/payment/manage/manage_view_model.dart
  13. 1 1
      packages/cpt_payment/lib/modules/payment/manage/manage_view_model.g.dart
  14. 172 0
      packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_page.dart
  15. 3 0
      packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_state.dart
  16. 25 0
      packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_view_model.dart
  17. 27 0
      packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_view_model.g.dart
  18. 184 0
      packages/cpt_payment/lib/modules/payment_info/payment_info_page.dart
  19. 25 0
      packages/cpt_payment/lib/modules/payment_info/payment_info_state.dart
  20. 19 0
      packages/cpt_payment/lib/modules/payment_info/payment_info_view_model.dart
  21. 27 0
      packages/cpt_payment/lib/modules/payment_info/payment_info_view_model.g.dart
  22. 116 0
      packages/cpt_payment/lib/modules/payment_success/payment_success_page.dart
  23. 3 0
      packages/cpt_payment/lib/modules/payment_success/payment_success_state.dart
  24. 13 0
      packages/cpt_payment/lib/modules/payment_success/payment_success_view_model.dart
  25. 27 0
      packages/cpt_payment/lib/modules/payment_success/payment_success_view_model.g.dart
  26. 12 4
      packages/cpt_payment/lib/router/component/payment_component_service.dart
  27. 10 0
      packages/cpt_payment/lib/router/page/payment_page_router.dart
  28. 100 0
      packages/cpt_payment/lib/router/page/payment_page_router.gr.dart
  29. BIN
      packages/cs_resources/assets/payment/american_express_icon.webp
  30. BIN
      packages/cs_resources/assets/payment/card_name.webp
  31. BIN
      packages/cs_resources/assets/payment/card_number.webp
  32. BIN
      packages/cs_resources/assets/payment/info_details.webp
  33. BIN
      packages/cs_resources/assets/payment/info_notes.webp
  34. BIN
      packages/cs_resources/assets/payment/master_card_icon.webp
  35. BIN
      packages/cs_resources/assets/payment/visa_icon.webp
  36. 7 0
      packages/cs_resources/lib/generated/assets.dart
  37. 6 0
      packages/cs_resources/lib/theme/app_colors_theme.dart
  38. 4 0
      packages/cs_router/lib/componentRouter/payment_service.dart
  39. 5 0
      packages/cs_router/lib/path/router_path.dart

+ 5 - 2
packages/cpt_facility/lib/modules/book_confirm/book_confirm_page.dart

@@ -116,7 +116,7 @@ class BookConfirmPage extends HookConsumerWidget {
           ),
 
           // 显示支付信息
-          _paymentInfo(context),
+          _paymentInfo(context,ref),
 
           // 底部按钮
           MyButton(
@@ -235,7 +235,9 @@ class BookConfirmPage extends HookConsumerWidget {
   }
 
   //底部的支付信息
-  Widget _paymentInfo(BuildContext context) {
+  Widget _paymentInfo(BuildContext context,WidgetRef ref) {
+    final viewModel = ref.watch(bookConfirmViewModelProvider.notifier);
+
     return Container(
       padding: const EdgeInsets.symmetric(vertical: 17.5, horizontal: 23),
       color: context.appColors.whiteBG,
@@ -268,6 +270,7 @@ class BookConfirmPage extends HookConsumerWidget {
                 textColor: Colors.white,
                 backgroundColor: context.appColors.btnBgDefault,
                 paddingRight: 16,
+                onClick: viewModel.gotoChooseCardPage,
                 paddingLeft: 16,
                 paddingTop: 8,
                 paddingBottom: 8,

+ 7 - 3
packages/cpt_facility/lib/modules/book_confirm/book_confirm_view_model.dart

@@ -1,6 +1,6 @@
 import 'package:cpt_facility/modules/detail/facility_detail_page.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:widgets/widget_export.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 
 import 'book_confirm_state.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
@@ -15,11 +15,15 @@ class BookConfirmViewModel extends _$BookConfirmViewModel {
   }
 
   //执行支付
-  void doPayment(){
-
+  void doPayment() {
     ToastEngine.show("点击了确定");
 
     FacilityDetailPage.startWithPop2Main();
   }
 
+  //选择银行卡页面
+  void gotoChooseCardPage() {
+    ComponentServiceManager().paymentService.startChooseCardPage();
+  }
+
 }

+ 222 - 0
packages/cpt_payment/lib/modules/add_card/add_card_page.dart

@@ -0,0 +1,222 @@
+import 'package:cpt_payment/modules/choose_card/choose_card_page.dart';
+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 'package:widgets/my_text_field.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../router/page/payment_page_router.dart';
+import 'add_card_state.dart';
+import 'add_card_view_model.dart';
+
+@RoutePage()
+class AddCardPage extends HookConsumerWidget {
+  const AddCardPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const AddCardPageRoute());
+    } else {
+      appRouter.push(const AddCardPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(addCardViewModelProvider.notifier);
+    final state = ref.watch(addCardViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.add_new_card),
+      backgroundColor: context.appColors.whiteBG,
+      body: SizedBox(
+        width: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    const Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceAround,
+                      children: [
+                        MyAssetImage(Assets.paymentMasterCardIcon, width: 51, height: 30.5),
+                        MyAssetImage(Assets.paymentVisaIcon, width: 78.5, height: 25.5),
+                        MyAssetImage(Assets.paymentAmericanExpressIcon, width: 47, height: 29),
+                      ],
+                    ).marginOnly(left: 20, right: 20, top: 32, bottom: 32),
+
+                    //信用卡
+                    MyTextView(
+                      S.current.credit_debit_card,
+                      fontSize: 17,
+                      marginLeft: 15,
+                      marginRight: 15,
+                      textColor: context.appColors.textBlack,
+                      isFontMedium: true,
+                    ),
+
+                    //持卡人姓名
+                    _buildInputLayout(
+                      context,
+                      state,
+                      "card_name",
+                      margin: const EdgeInsets.only(left: 15, right: 15, top: 16),
+                      leftIcon: Assets.paymentCardName,
+                      textInputType: TextInputType.text,
+                      textInputAction: TextInputAction.next,
+                      onSubmit: (formKey, value) {
+                        state.formData[formKey]!['focusNode'].unfocus();
+                        FocusScope.of(context).requestFocus(state.formData['card_number']!['focusNode']);
+                      },
+                    ),
+
+                    //卡号
+                    _buildInputLayout(
+                      context,
+                      state,
+                      "card_number",
+                      margin: const EdgeInsets.only(left: 15, right: 15, top: 10, bottom: 21),
+                      leftIcon: Assets.paymentCardNumber,
+                      textInputType: TextInputType.number,
+                      textInputAction: TextInputAction.next,
+                      onSubmit: (formKey, value) {
+                        state.formData[formKey]!['focusNode'].unfocus();
+                        FocusScope.of(context).requestFocus(state.formData['month']!['focusNode']);
+                      },
+                    ),
+
+                    //月份,年份,验证码
+                    Row(
+                      children: [
+                        //月份
+                        _buildInputLayout(
+                          context,
+                          state,
+                          "month",
+                          margin: const EdgeInsets.only(left: 15),
+                          showLeftIcon: false,
+                          textInputType: TextInputType.number,
+                          textInputAction: TextInputAction.next,
+                          onSubmit: (formKey, value) {
+                            state.formData[formKey]!['focusNode'].unfocus();
+                            FocusScope.of(context).requestFocus(state.formData['year']!['focusNode']);
+                          },
+                        ).expanded(),
+
+                        //年份
+                        _buildInputLayout(
+                          context,
+                          state,
+                          "year",
+                          margin: const EdgeInsets.only(left: 8.5, right: 8.5),
+                          showLeftIcon: false,
+                          textInputType: TextInputType.number,
+                          textInputAction: TextInputAction.next,
+                          onSubmit: (formKey, value) {
+                            state.formData[formKey]!['focusNode'].unfocus();
+                            FocusScope.of(context).requestFocus(state.formData['cyc']!['focusNode']);
+                          },
+                        ).expanded(),
+
+                        //验证码
+                        _buildInputLayout(
+                          context,
+                          state,
+                          "cyc",
+                          margin: const EdgeInsets.only(right: 15),
+                          showLeftIcon: false,
+                          textInputType: TextInputType.number,
+                          textInputAction: TextInputAction.next,
+                          onSubmit: (formKey, value) {
+                            state.formData[formKey]!['focusNode'].unfocus();
+                          },
+                        ).expanded(),
+                      ],
+                    )
+                  ],
+                )).expanded(),
+
+            //底部按钮
+            MyButton(
+              onPressed: viewModel.addCard,
+              text: S.current.add_card,
+              textColor: Colors.white,
+              backgroundColor: context.appColors.btnBgDefault,
+              fontWeight: FontWeight.w500,
+              type: ClickType.throttle,
+              fontSize: 16,
+              minHeight: 50,
+              radius: 0,
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildInputLayout(
+    BuildContext context,
+    AddCardState state,
+    String key, {
+    EdgeInsetsGeometry? margin,
+    bool showRightIcon = false, //是否展示右侧的布局
+    bool showLeftIcon = true, //是否展示左侧侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? leftIcon,
+    String? errorText,
+    bool obscureText = false,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintText: state.formData[key]!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHintDark,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w400,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: margin ?? EdgeInsets.zero,
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w400,
+        ),
+        inputType: textInputType,
+        textInputAction: textInputAction,
+        onSubmit: onSubmit,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: obscureText,
+        errorText: errorText,
+        showLeftIcon: showLeftIcon,
+        leftWidget: showLeftIcon ? MyAssetImage(leftIcon ?? "", width: 27, height: 27) : const SizedBox(),
+        showRightIcon: showRightIcon,
+        rightWidget: rightWidget,
+      ),
+    );
+  }
+}

+ 48 - 0
packages/cpt_payment/lib/modules/add_card/add_card_state.dart

@@ -0,0 +1,48 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class AddCardState {
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  AddCardState({
+    Map<String, Map<String, dynamic>>? formData,
+  }) : formData = formData ??
+            {
+              'card_name': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': S.current.name_on_card,
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'card_number': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': S.current.card_number,
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'month': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': 'MM',
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'year': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': 'YY',
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'cyc': {
+                'value': '',
+                'controller': TextEditingController(),
+                'hintText': 'CYC',
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+            };
+}

+ 76 - 0
packages/cpt_payment/lib/modules/add_card/add_card_view_model.dart

@@ -0,0 +1,76 @@
+import 'package:flutter/material.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:shared/utils/util.dart';
+
+import 'add_card_state.dart';
+
+part 'add_card_view_model.g.dart';
+
+@riverpod
+class AddCardViewModel extends _$AddCardViewModel {
+  @override
+  AddCardState build() {
+    return AddCardState();
+  }
+
+  //添加银行卡
+  void addCard() {
+
+    final FocusNode cardNameFocusNode = state.formData['card_name']!['focusNode'];
+    final FocusNode cardNumFocusNode = state.formData['card_number']!['focusNode'];
+    final FocusNode monthFocusNode = state.formData['month']!['focusNode'];
+    final FocusNode yearFocusNode = state.formData['year']!['focusNode'];
+    final FocusNode cycFocusNode = state.formData['cyc']!['focusNode'];
+
+    final TextEditingController cardNameController = state.formData['card_name']!['controller'];
+    final TextEditingController cardNumController = state.formData['card_number']!['controller'];
+    final TextEditingController monthController = state.formData['month']!['controller'];
+    final TextEditingController yearController = state.formData['year']!['controller'];
+    final TextEditingController cycController = state.formData['cyc']!['controller'];
+
+    cardNameFocusNode.unfocus();
+    cardNumFocusNode.unfocus();
+    monthFocusNode.unfocus();
+    yearFocusNode.unfocus();
+    cycFocusNode.unfocus();
+
+    final cardName = cardNameController.text;
+    final cardNum = cardNumController.text;
+    final month = monthController.text;
+    final year = yearController.text;
+    final cyc = cycController.text;
+
+    Log.d('当前待提交的 cardName:${cardName} cardNum:${cardNum} month:${month} year:${year} cyc:${cyc}');
+
+    if (Utils.isEmpty(cardName)) {
+      ToastEngine.show('Enter Name on Card');
+      return;
+    }
+
+    if (Utils.isEmpty(cardNum)) {
+      ToastEngine.show('Enter Card Number');
+      return;
+    }
+
+    if (Utils.isEmpty(month)) {
+      ToastEngine.show('Enter Month on Card');
+      return;
+    }
+
+    if (Utils.isEmpty(year)) {
+      ToastEngine.show('Enter Year on Card');
+      return;
+    }
+
+    if (Utils.isEmpty(cyc)) {
+      ToastEngine.show('Enter CYC on Card');
+      return;
+    }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求 cardName:${cardName} cardNum:${cardNum} month:${month} year:${year} cyc:${cyc}');
+
+  }
+}

+ 26 - 0
packages/cpt_payment/lib/modules/add_card/add_card_view_model.g.dart

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

+ 128 - 0
packages/cpt_payment/lib/modules/choose_card/choose_card_page.dart

@@ -0,0 +1,128 @@
+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:flutter_hooks/flutter_hooks.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/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../router/page/payment_page_router.dart';
+import '../payment/manage/item_manage.dart';
+import 'choose_card_view_model.dart';
+
+@RoutePage()
+class ChooseCardPage extends HookConsumerWidget {
+  const ChooseCardPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const ChooseCardPageRoute());
+    } else {
+      appRouter.push(const ChooseCardPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(chooseCardViewModelProvider.notifier);
+    final state = ref.watch(chooseCardViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        S.current.payment,
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDark,
+      body: SizedBox(
+        width: double.infinity,
+        height: double.infinity,
+        child: Column(
+          children: [
+            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).expanded(),
+
+            //底部按钮(其实就是返回)
+            MyButton(
+              onPressed: () {
+                context.appRouter.maybePop();
+              },
+              text: S.current.next,
+              textColor: Colors.white,
+              backgroundColor: context.appColors.btnBgDefault,
+              fontWeight: FontWeight.w500,
+              type: ClickType.throttle,
+              fontSize: 16,
+              minHeight: 50,
+              radius: 0,
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 32 - 0
packages/cpt_payment/lib/modules/choose_card/choose_card_state.dart

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

+ 168 - 0
packages/cpt_payment/lib/modules/choose_card/choose_card_view_model.dart

@@ -0,0 +1,168 @@
+import 'package:cpt_payment/modules/add_card/add_card_page.dart';
+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:widgets/dialog/app_default_dialog.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'choose_card_state.dart';
+
+part 'choose_card_view_model.g.dart';
+
+@riverpod
+class ChooseCardViewModel extends _$ChooseCardViewModel {
+  @override
+  ChooseCardState build() {
+    return ChooseCardState(datas: []);
+  }
+
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
+  );
+
+  //刷新页面状态
+  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() {
+    AddCardPage.startInstance();
+  }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/choose_card/choose_card_view_model.g.dart

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

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

@@ -1,4 +1,5 @@
 import 'package:auto_route/auto_route.dart';
+import 'package:cpt_payment/modules/payment_info/payment_info_page.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -43,7 +44,8 @@ class CondoPaymentScreen extends HookConsumerWidget {
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
                     return CondoPaymentItem(index: index, item: state.datas[index]).onTap(() {
-
+                      //去信息页面
+                      PaymentInfoPage.startInstance(context: context);
                     });
                   },
                   childCount: state.datas.length,

+ 2 - 1
packages/cpt_payment/lib/modules/payment/manage/manage_view_model.dart

@@ -6,6 +6,7 @@ import 'package:widgets/dialog/app_default_dialog.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../../add_card/add_card_page.dart';
 import 'manage_state.dart';
 
 part 'manage_view_model.g.dart';
@@ -163,7 +164,7 @@ class ManageViewModel extends _$ManageViewModel {
 
   //去添加新卡的页面
   void gotoAddCardPage() {
-
+    AddCardPage.startInstance();
   }
 
 }

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

@@ -6,7 +6,7 @@ part of 'manage_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$manageViewModelHash() => r'9e6b2c00e4ed57279830e8738a899e01543b4783';
+String _$manageViewModelHash() => r'293b21a526990c4b60cd1875304d814dbd719f8e';
 
 /// See also [ManageViewModel].
 @ProviderFor(ManageViewModel)

+ 172 - 0
packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_page.dart

@@ -0,0 +1,172 @@
+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/payment_page_router.dart';
+import 'payment_confirm_view_model.dart';
+
+@RoutePage()
+class PaymentConfirmPage extends HookConsumerWidget {
+  const PaymentConfirmPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const PaymentConfirmPageRoute());
+    } else {
+      appRouter.push(const PaymentConfirmPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(paymentConfirmViewModelProvider.notifier);
+    final state = ref.watch(paymentConfirmViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, "付款的标题"),
+      backgroundColor: context.appColors.whiteBG,
+      body: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          SingleChildScrollView(
+            scrollDirection: Axis.vertical,
+            physics: const BouncingScrollPhysics(),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                //金额
+                Row(
+                  children: [
+                    const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
+                    MyTextView(
+                      S.current.payment_details,
+                      textColor: context.appColors.textBlack,
+                      fontSize: 17,
+                      marginLeft: 14,
+                      isFontMedium: true,
+                    ).expanded(),
+                  ],
+                ).marginOnly(top: 15, left: 15, right: 15),
+
+                Row(
+                  children: [
+                    MyTextView(
+                      "SGD",
+                      textColor: context.appColors.textBlack,
+                      fontSize: 18,
+                      isFontRegular: true,
+                    ),
+                    MyTextView(
+                      "\$21.80",
+                      textColor: context.appColors.textPrimary,
+                      fontSize: 22,
+                      marginLeft: 12,
+                      isFontMedium: true,
+                    ).expanded(),
+                  ],
+                ).marginOnly(top: 20, left: 15, right: 15),
+
+                Container(
+                  height: 0.5,
+                  margin: const EdgeInsets.only(top: 22, bottom: 13.5, left: 15, right: 15),
+                  color: context.appColors.dividerDefault,
+                ),
+
+                // DESC
+                Row(
+                  children: [
+                    const MyAssetImage(Assets.paymentInfoNotes, width: 27, height: 27),
+                    MyTextView(
+                      S.current.notes_to_recipient,
+                      textColor: context.appColors.textBlack,
+                      fontSize: 17,
+                      marginLeft: 14,
+                      isFontMedium: true,
+                    ).expanded(),
+                  ],
+                ).marginOnly(left: 15, right: 15),
+
+                MyTextView(
+                  "The money has already been paid",
+                  textColor: context.appColors.textPrimary,
+                  fontSize: 16,
+                  marginTop: 15,
+                  marginBottom: 20,
+                  marginLeft: 15,
+                  marginRight: 15,
+                  isFontRegular: true,
+                ),
+
+                _paymentInfo(context,ref),
+              ],
+            ),
+          ).expanded(),
+
+          // 底部按钮
+          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),
+        ],
+      ),
+    );
+  }
+
+  //底部的支付信息
+  Widget _paymentInfo(BuildContext context,WidgetRef ref) {
+    final viewModel = ref.watch(paymentConfirmViewModelProvider.notifier);
+
+    return Container(
+        height: 75,
+        padding: const EdgeInsets.symmetric(horizontal: 20),
+        color: context.appColors.backgroundDark,
+        child: Row(
+          children: [
+            const MyAssetImage(
+              Assets.paymentMasterCardIcon,
+              height: 34,
+              width: 56,
+            ),
+            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,
+              onClick: viewModel.gotoChooseCardPage,
+              paddingBottom: 8,
+              cornerRadius: 7,
+              fontSize: 15,
+              isFontMedium: true,
+            )
+          ],
+        ));
+  }
+}

+ 3 - 0
packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_state.dart

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

+ 25 - 0
packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_view_model.dart

@@ -0,0 +1,25 @@
+import 'package:cpt_payment/modules/choose_card/choose_card_page.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import '../payment_success/payment_success_page.dart';
+import 'payment_confirm_state.dart';
+
+part 'payment_confirm_view_model.g.dart';
+
+@riverpod
+class PaymentConfirmViewModel extends _$PaymentConfirmViewModel {
+  @override
+  PaymentConfirmState build() {
+    return PaymentConfirmState();
+  }
+
+  //执行支付
+  void doPayment() {
+    PaymentSuccessPage.startWithPop();
+  }
+
+  //去设置银行卡页面
+  void gotoChooseCardPage() {
+    ChooseCardPage.startInstance();
+  }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment_confirm/payment_confirm_view_model.g.dart

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

+ 184 - 0
packages/cpt_payment/lib/modules/payment_info/payment_info_page.dart

@@ -0,0 +1,184 @@
+import 'package:cpt_payment/modules/payment/condo/active/condo_active_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';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.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: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 'package:widgets/widget_export.dart';
+import '../../router/page/payment_page_router.dart';
+import 'payment_info_view_model.dart';
+
+@RoutePage()
+class PaymentInfoPage extends HookConsumerWidget {
+  const PaymentInfoPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const PaymentInfoPageRoute());
+    } else {
+      appRouter.push(const PaymentInfoPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(paymentInfoViewModelProvider.notifier);
+    final state = ref.watch(paymentInfoViewModelProvider);
+    final noteCount = useState(0);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, "付款的标题"),
+      backgroundColor: context.appColors.whiteBG,
+      body: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          SingleChildScrollView(
+                  scrollDirection: Axis.vertical,
+                  physics: const BouncingScrollPhysics(),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      //金额
+                      Row(
+                        children: [
+                          const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
+                          MyTextView(
+                            S.current.payment_details,
+                            textColor: context.appColors.textBlack,
+                            fontSize: 17,
+                            marginLeft: 14,
+                            isFontMedium: true,
+                          ).expanded(),
+                        ],
+                      ).marginOnly(top: 15),
+
+                      Row(
+                        children: [
+                          MyTextView(
+                            "SGD",
+                            textColor: context.appColors.textBlack,
+                            fontSize: 18,
+                            isFontRegular: true,
+                          ),
+                          MyTextView(
+                            "\$21.80",
+                            textColor: context.appColors.textPrimary,
+                            fontSize: 22,
+                            marginLeft: 12,
+                            isFontMedium: true,
+                          ).expanded(),
+                        ],
+                      ).marginOnly(top: 20),
+
+                      Container(
+                        height: 0.5,
+                        margin: const EdgeInsets.only(top: 22,bottom: 13.5),
+                        color: context.appColors.dividerDefault,
+                      ),
+
+                      // DESC
+                      Row(
+                        children: [
+                          const MyAssetImage(Assets.paymentInfoNotes, width: 27, height: 27),
+                          MyTextView(
+                            S.current.notes_to_recipient,
+                            textColor: context.appColors.textBlack,
+                            fontSize: 17,
+                            marginLeft: 14,
+                            isFontMedium: true,
+                          ).expanded(),
+                        ],
+                      ),
+
+                      //大文本框
+                      IgnoreKeyboardDismiss(
+                        child: Container(
+                          height: 177,
+                          margin: const EdgeInsets.only(top: 24),
+                          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                          decoration: BoxDecoration(
+                            color: context.appColors.authFiledBG,
+                            borderRadius: const BorderRadius.all(Radius.circular(5)),
+                          ),
+                          child: Stack(
+                            children: [
+                              TextField(
+                                cursorColor: context.appColors.authFiledText,
+                                cursorWidth: 1.5,
+                                autofocus: false,
+                                enabled: true,
+                                focusNode: state.formData["note"]!['focusNode'],
+                                controller: state.formData["note"]!['controller'],
+                                decoration: InputDecoration(
+                                  isDense: true,
+                                  isCollapsed: true,
+                                  border: InputBorder.none,
+                                  hintText: state.formData["note"]!['hintText'],
+                                  hintStyle: TextStyle(
+                                    color: context.appColors.authFiledHint,
+                                    fontSize: 16.0,
+                                    fontWeight: FontWeight.w500,
+                                  ),
+                                ),
+                                style: TextStyle(
+                                  color: context.appColors.authFiledText,
+                                  fontSize: 16.0,
+                                  fontWeight: FontWeight.w500,
+                                ),
+                                textInputAction: TextInputAction.done,
+                                onSubmitted: (value) {
+                                  FocusScope.of(context).unfocus();
+                                },
+                                maxLines: null,
+                                expands: true,
+                                onChanged: (text) {
+                                  // 当文本改变时,更新字符数量
+                                  noteCount.value = text.length;
+                                },
+                              ),
+                              Positioned(
+                                bottom: 0.0,
+                                right: 0.0,
+                                child: Text(
+                                  S.current.characters(noteCount.value),
+                                  style: TextStyle(
+                                    color: context.appColors.textBlack,
+                                    fontSize: 15.0,
+                                  ),
+                                ),
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ],
+                  ).paddingSymmetric(horizontal: 15))
+              .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,
+          ).marginOnly(top: 15),
+        ],
+      ),
+    );
+  }
+}

+ 25 - 0
packages/cpt_payment/lib/modules/payment_info/payment_info_state.dart

@@ -0,0 +1,25 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class PaymentInfoState{
+
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  // ===================================  Begin  ↓  ===================================
+
+  PaymentInfoState({
+    Map<String, Map<String, dynamic>>? formData,
+  }) : formData = formData ??
+      {
+        'note': {
+          'value': '',
+          'controller': TextEditingController(),
+          'focusNode': FocusNode(),
+          'hintText': S.current.type_here,
+          'obsecure': false,
+        },
+      };
+
+
+}

+ 19 - 0
packages/cpt_payment/lib/modules/payment_info/payment_info_view_model.dart

@@ -0,0 +1,19 @@
+import 'package:cpt_payment/modules/payment_confirm/payment_confirm_page.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'payment_info_state.dart';
+
+part 'payment_info_view_model.g.dart';
+
+@riverpod
+class PaymentInfoViewModel extends _$PaymentInfoViewModel {
+  @override
+  PaymentInfoState build() {
+    return PaymentInfoState();
+  }
+
+  //去确定页面
+  void gotoConfirmPage() {
+    PaymentConfirmPage.startInstance();
+  }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment_info/payment_info_view_model.g.dart

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

+ 116 - 0
packages/cpt_payment/lib/modules/payment_success/payment_success_page.dart

@@ -0,0 +1,116 @@
+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_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../router/page/payment_page_router.dart';
+import 'payment_success_view_model.dart';
+
+@RoutePage()
+class PaymentSuccessPage extends HookConsumerWidget {
+  const PaymentSuccessPage({Key? key}) : super(key: key);
+
+
+  //启动并关闭其他栈
+  static void startWithPop() {
+    appRouter.pushAndPopUntil(
+      const PaymentSuccessPageRoute(),
+      predicate: (route) {
+        return route.settings.name == 'PaymentPageRoute';
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(paymentSuccessViewModelProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, "付款的标题"),
+      backgroundColor: context.appColors.whiteBG,
+      body: SizedBox(
+        width: double.infinity,
+        child: Column(
+          children: [
+            //成功图片
+            const MyAssetImage(
+              Assets.facilityPaymentSuccessIcon,
+              width: 54,
+              height: 54,
+            ).marginOnly(top: 11, bottom: 13),
+
+            //支付成功
+            MyTextView(
+              S.current.booking_successful,
+              fontSize: 18,
+              marginBottom: 3,
+              isFontMedium: true,
+              textColor: context.appColors.textPrimary,
+            ),
+
+            //支付金额
+            MyTextView(
+              S.current.fee_paid,
+              marginTop: 40,
+              fontSize: 15,
+              isFontRegular: true,
+              textColor: context.appColors.textBlack,
+            ),
+            MyTextView(
+              "\$10.80",
+              fontSize: 15,
+              isFontRegular: true,
+              textColor: context.appColors.textPrimary,
+            ),
+
+            //付款类型与时间
+            Row(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                MyTextView(
+                  "Master card ending",
+                  fontSize: 15,
+                  isFontRegular: true,
+                  textColor: context.appColors.textBlack,
+                ),
+                MyTextView(
+                  "9423",
+                  fontSize: 15,
+                  isFontMedium: true,
+                  textColor: context.appColors.textBlack,
+                ),
+              ],
+            ).marginOnly(top: 12),
+
+            Row(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                MyTextView(
+                  S.current.paid_on,
+                  fontSize: 15,
+                  isFontRegular: true,
+                  textColor: context.appColors.textBlack,
+                ),
+                MyTextView(
+                  "24 Oct 2023 at 02:19 PM",
+                  fontSize: 15,
+                  isFontMedium: true,
+                  textColor: context.appColors.textBlack,
+                ),
+              ],
+            ).marginOnly(top: 5),
+
+            const SizedBox(height: 23),
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 3 - 0
packages/cpt_payment/lib/modules/payment_success/payment_success_state.dart

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

+ 13 - 0
packages/cpt_payment/lib/modules/payment_success/payment_success_view_model.dart

@@ -0,0 +1,13 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'payment_success_state.dart';
+
+part 'payment_success_view_model.g.dart';
+
+@riverpod
+class PaymentSuccessViewModel extends _$PaymentSuccessViewModel {
+  @override
+  PaymentSuccessState build() {
+    return PaymentSuccessState();
+  }
+}

+ 27 - 0
packages/cpt_payment/lib/modules/payment_success/payment_success_view_model.g.dart

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

+ 12 - 4
packages/cpt_payment/lib/router/component/payment_component_service.dart

@@ -1,15 +1,14 @@
 /*
  * Community 组件的组件路由
  */
-import 'package:flutter/cupertino.dart';
+import 'package:cpt_payment/modules/add_card/add_card_page.dart';
+import 'package:cpt_payment/modules/choose_card/choose_card_page.dart';
 import 'package:router/componentRouter/payment_service.dart';
-import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
 import '../../modules/payment/payment_page.dart';
 
-
 part 'payment_component_service.g.dart';
 
 @Riverpod(keepAlive: true)
@@ -18,9 +17,18 @@ PaymentService paymentService(Ref ref) {
 }
 
 class PaymentComponentService extends PaymentService {
-
   @override
   void startPaymentPage() {
     PaymentPage.startInstance();
   }
+
+  @override
+  void startAddCardPage() {
+    AddCardPage.startInstance();
+  }
+
+  @override
+  void startChooseCardPage() {
+    ChooseCardPage.startInstance();
+  }
 }

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

@@ -9,6 +9,11 @@ import '../../modules/payment/manage/manage_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';
+import '../../modules/payment_info/payment_info_page.dart';
+import '../../modules/payment_confirm/payment_confirm_page.dart';
+import '../../modules/payment_success/payment_success_page.dart';
+import '../../modules/add_card/add_card_page.dart';
+import '../../modules/choose_card/choose_card_page.dart';
 
 part 'payment_page_router.gr.dart';
 
@@ -31,5 +36,10 @@ class PaymentPageRouter extends _$PaymentPageRouter {
             AutoRoute(page: ManagePageRoute.page, path: 'manage'),
           ],
         ),
+        CustomRoute(page: PaymentInfoPageRoute.page, path: RouterPath.paymentInfo, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: PaymentConfirmPageRoute.page, path: RouterPath.paymentConfirm, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: PaymentSuccessPageRoute.page, path: RouterPath.paymentSuccess, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: AddCardPageRoute.page, path: RouterPath.paymentAddCard, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: ChooseCardPageRoute.page, path: RouterPath.paymentChooseCard, transitionsBuilder: applySlideTransition),
       ];
 }

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

@@ -15,6 +15,18 @@ abstract class _$PaymentPageRouter extends RootStackRouter {
 
   @override
   final Map<String, PageFactory> pagesMap = {
+    AddCardPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const AddCardPage(),
+      );
+    },
+    ChooseCardPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const ChooseCardPage(),
+      );
+    },
     CondoActivePageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -45,16 +57,62 @@ abstract class _$PaymentPageRouter extends RootStackRouter {
         child: ManageScreen(),
       );
     },
+    PaymentConfirmPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const PaymentConfirmPage(),
+      );
+    },
+    PaymentInfoPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const PaymentInfoPage(),
+      );
+    },
     PaymentPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const PaymentPage(),
       );
     },
+    PaymentSuccessPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const PaymentSuccessPage(),
+      );
+    },
   };
 }
 
 /// generated route for
+/// [AddCardPage]
+class AddCardPageRoute extends PageRouteInfo<void> {
+  const AddCardPageRoute({List<PageRouteInfo>? children})
+      : super(
+          AddCardPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'AddCardPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [ChooseCardPage]
+class ChooseCardPageRoute extends PageRouteInfo<void> {
+  const ChooseCardPageRoute({List<PageRouteInfo>? children})
+      : super(
+          ChooseCardPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'ChooseCardPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [CondoActiveScreen]
 class CondoActivePageRoute extends PageRouteInfo<void> {
   const CondoActivePageRoute({List<PageRouteInfo>? children})
@@ -125,6 +183,34 @@ class ManagePageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [PaymentConfirmPage]
+class PaymentConfirmPageRoute extends PageRouteInfo<void> {
+  const PaymentConfirmPageRoute({List<PageRouteInfo>? children})
+      : super(
+          PaymentConfirmPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'PaymentConfirmPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [PaymentInfoPage]
+class PaymentInfoPageRoute extends PageRouteInfo<void> {
+  const PaymentInfoPageRoute({List<PageRouteInfo>? children})
+      : super(
+          PaymentInfoPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'PaymentInfoPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [PaymentPage]
 class PaymentPageRoute extends PageRouteInfo<void> {
   const PaymentPageRoute({List<PageRouteInfo>? children})
@@ -137,3 +223,17 @@ class PaymentPageRoute extends PageRouteInfo<void> {
 
   static const PageInfo<void> page = PageInfo<void>(name);
 }
+
+/// generated route for
+/// [PaymentSuccessPage]
+class PaymentSuccessPageRoute extends PageRouteInfo<void> {
+  const PaymentSuccessPageRoute({List<PageRouteInfo>? children})
+      : super(
+          PaymentSuccessPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'PaymentSuccessPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}

BIN
packages/cs_resources/assets/payment/american_express_icon.webp


BIN
packages/cs_resources/assets/payment/card_name.webp


BIN
packages/cs_resources/assets/payment/card_number.webp


BIN
packages/cs_resources/assets/payment/info_details.webp


BIN
packages/cs_resources/assets/payment/info_notes.webp


BIN
packages/cs_resources/assets/payment/master_card_icon.webp


BIN
packages/cs_resources/assets/payment/visa_icon.webp


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

@@ -122,15 +122,22 @@ class Assets {
   static const String noticeBoardAnnouncementIcon = 'assets/notice_board/announcement_icon.png';
   static const String noticeBoardDocumentsIcon = 'assets/notice_board/documents_icon.png';
   static const String noticeBoardEventIcon = 'assets/notice_board/event_icon.png';
+  static const String paymentAmericanExpressIcon = 'assets/payment/american_express_icon.webp';
+  static const String paymentCardName = 'assets/payment/card_name.webp';
+  static const String paymentCardNumber = 'assets/payment/card_number.webp';
   static const String paymentCondoIcon = 'assets/payment/condo_icon.webp';
   static const String paymentInfoBusiness = 'assets/payment/info_business.webp';
   static const String paymentInfoCardGroup = 'assets/payment/info_card_group.webp';
   static const String paymentInfoCashBack = 'assets/payment/info_cash_back.webp';
+  static const String paymentInfoDetails = 'assets/payment/info_details.webp';
   static const String paymentInfoIcon = 'assets/payment/info_icon.webp';
+  static const String paymentInfoNotes = 'assets/payment/info_notes.webp';
   static const String paymentInfoRewards = 'assets/payment/info_rewards.webp';
   static const String paymentInfoTopImage = 'assets/payment/info_top_image.webp';
   static const String paymentManageIcon = 'assets/payment/manage_icon.webp';
+  static const String paymentMasterCardIcon = 'assets/payment/master_card_icon.webp';
   static const String paymentTitleQuestionIcon = 'assets/payment/title_question_icon.webp';
+  static const String paymentVisaIcon = 'assets/payment/visa_icon.webp';
   static const String profileEditDialogDelete = 'assets/profile/edit_dialog_delete.webp';
   static const String profileEditDialogUpload = 'assets/profile/edit_dialog_upload.webp';
   static const String profileEditProfileAdd = 'assets/profile/edit_profile_add.webp';

+ 6 - 0
packages/cs_resources/lib/theme/app_colors_theme.dart

@@ -32,6 +32,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   static const _colorB4C5FF = Color(0xFFB4C5FF);
   static const _colorFE4066 = Color(0xFFFE4066);
   static const _colorE9E9E9 = Color(0xFFE9E9E9);
+  static const _color99A8CA = Color(0xFF99A8CA);
 
   //暗色主题的一些自定义颜色值
   static const _darkBlackBg = Color(0xFF0F0F0F);
@@ -73,6 +74,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   final Color deleteRed; //删除的红色
   final Color grayBgE9; //e9灰色背景
   final Color disEnableGray; //禁用的灰色
+  final Color authFiledHintDark; //文本Hint的深蓝色
 
   // 私有的构造函数
   const AppColorsTheme._internal({
@@ -107,6 +109,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
     required this.deleteRed,
     required this.grayBgE9,
     required this.disEnableGray,
+    required this.authFiledHintDark,
   });
 
   // 浅色主题工厂方法
@@ -143,6 +146,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       deleteRed: _colorFE4066,
       grayBgE9: _colorE9E9E9,
       disEnableGray: _colorBDBDBD,
+      authFiledHintDark: _color99A8CA,
     );
   }
 
@@ -180,6 +184,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       deleteRed: Colors.white,
       grayBgE9: _darkBlackItemLightMost,
       disEnableGray: _darkBlackItemLight,
+      authFiledHintDark: _color99A8CA,
     );
   }
 
@@ -226,6 +231,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       deleteRed: Color.lerp(deleteRed, other.deleteRed, t)!,
       grayBgE9: Color.lerp(grayBgE9, other.grayBgE9, t)!,
       disEnableGray: Color.lerp(disEnableGray, other.disEnableGray, t)!,
+      authFiledHintDark: Color.lerp(authFiledHintDark, other.authFiledHintDark, t)!,
     );
   }
 }

+ 4 - 0
packages/cs_router/lib/componentRouter/payment_service.dart

@@ -5,4 +5,8 @@ abstract class PaymentService {
 
   void startPaymentPage();
 
+  void startChooseCardPage();
+
+  void startAddCardPage();
+
 }

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

@@ -75,6 +75,11 @@ class RouterPath {
 
   //支付
   static const payment = '/payment';
+  static const paymentInfo = '/payment/info';
+  static const paymentConfirm = '/payment/confirm';
+  static const paymentSuccess = '/payment/success';
+  static const paymentAddCard = '/payment/add';
+  static const paymentChooseCard = '/payment/choose';
 
   //房屋资产
   static const property = '/property';