Browse Source

update community

glglove 3 months ago
parent
commit
14c1191108
100 changed files with 5934 additions and 680 deletions
  1. 1 1
      app/lib/modules/splash/vm/splash_view_model.dart
  2. 1 2
      packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.dart
  3. 1 1
      packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.g.dart
  4. 117 0
      packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_page.dart
  5. 22 0
      packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_view_model.dart
  6. 27 0
      packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_view_model.g.dart
  7. 5 18
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart
  8. 1 1
      packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.g.dart
  9. 14 9
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart
  10. 69 8
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart
  11. 1 1
      packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.g.dart
  12. 61 0
      packages/cpt_auth/lib/modules/select_estate/attach_input_widget.dart
  13. 74 0
      packages/cpt_auth/lib/modules/select_estate/dialog/attach_search_dialog.dart
  14. 128 114
      packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart
  15. 29 3
      packages/cpt_auth/lib/modules/select_estate/select_estate_state.dart
  16. 74 4
      packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.dart
  17. 1 1
      packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.g.dart
  18. 7 0
      packages/cpt_auth/lib/modules/select_role/select_role_view_model.dart
  19. 1 1
      packages/cpt_auth/lib/modules/select_role/select_role_view_model.g.dart
  20. 9 5
      packages/cpt_auth/lib/modules/select_unit/select_unit_page.dart
  21. 0 12
      packages/cpt_auth/lib/modules/select_unit/select_unit_state.dart
  22. 60 5
      packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.dart
  23. 1 1
      packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.g.dart
  24. 0 2
      packages/cpt_auth/lib/modules/sign_up/sign_up_view_model.dart
  25. 5 4
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart
  26. 0 1
      packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_view_model.dart
  27. 1 1
      packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.dart
  28. 1 1
      packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.g.dart
  29. 1 15
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_page.dart
  30. 4 6
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_state.dart
  31. 48 7
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.dart
  32. 1 1
      packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.g.dart
  33. 3 0
      packages/cpt_auth/lib/router/page/auth_page_router.dart
  34. 58 27
      packages/cpt_auth/lib/router/page/auth_page_router.gr.dart
  35. 68 61
      packages/cpt_main/lib/modules/me/me_page.dart
  36. 27 2
      packages/cpt_main/lib/modules/me/me_view_model.dart
  37. 11 7
      packages/cpt_notice_board/lib/modules/announcement_detail/page/announcement_detail_page.dart
  38. 25 29
      packages/cpt_notice_board/lib/modules/event/page/event_page.dart
  39. 8 5
      packages/cpt_notice_board/lib/modules/event_detail/page/event_detail_page.dart
  40. 2 5
      packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart
  41. 69 22
      packages/cpt_profile/lib/modules/change_mobile/change_mobile_view_model.dart
  42. 0 6
      packages/cpt_profile/lib/modules/my_estate/estate_group_data.dart
  43. 12 10
      packages/cpt_profile/lib/modules/my_estate/item_estate.dart
  44. 10 7
      packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart
  45. 3 3
      packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart
  46. 103 97
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart
  47. 10 10
      packages/cpt_profile/lib/modules/my_household/item_household.dart
  48. 3 3
      packages/cpt_profile/lib/modules/my_household/my_household_page.dart
  49. 3 2
      packages/cpt_profile/lib/modules/my_household/my_household_state.dart
  50. 30 78
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart
  51. 11 3
      packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart
  52. 10 17
      packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart
  53. 4 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart
  54. 87 7
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart
  55. 3 0
      packages/cpt_profile/lib/modules/reset_password/reset_password_page.dart
  56. 64 7
      packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.dart
  57. 0 33
      packages/cpt_rewards/lib/modules/rewards/page/rewards_page.dart
  58. 918 0
      packages/cpt_rewards/lib/modules/rewards/rewards_page.dart
  59. 70 0
      packages/cpt_rewards/lib/modules/rewards/rewards_repository.dart
  60. 27 0
      packages/cpt_rewards/lib/modules/rewards/rewards_repository.g.dart
  61. 49 0
      packages/cpt_rewards/lib/modules/rewards/rewards_state.dart
  62. 108 0
      packages/cpt_rewards/lib/modules/rewards/rewards_vm.dart
  63. 25 0
      packages/cpt_rewards/lib/modules/rewards/rewards_vm.g.dart
  64. 0 14
      packages/cpt_rewards/lib/modules/rewards/vm/rewards_view_model.dart
  65. 170 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_page.dart
  66. 70 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_repository.dart
  67. 27 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_repository.g.dart
  68. 49 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_state.dart
  69. 109 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_vm.dart
  70. 25 0
      packages/cpt_rewards/lib/modules/rewards_address/rewards_address_vm.g.dart
  71. 129 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_page.dart
  72. 70 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_repository.dart
  73. 27 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_repository.g.dart
  74. 49 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_state.dart
  75. 109 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_vm.dart
  76. 25 0
      packages/cpt_rewards/lib/modules/rewards_code/rewards_code_vm.g.dart
  77. 144 0
      packages/cpt_rewards/lib/modules/rewards_confirm/dialog/account_deactivation_dialog.dart
  78. 388 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_page.dart
  79. 70 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_repository.dart
  80. 27 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_repository.g.dart
  81. 49 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_state.dart
  82. 118 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_vm.dart
  83. 25 0
      packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_vm.g.dart
  84. 632 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_page.dart
  85. 70 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_repository.dart
  86. 27 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_repository.g.dart
  87. 49 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_state.dart
  88. 109 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_vm.dart
  89. 25 0
      packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_vm.g.dart
  90. 130 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_page.dart
  91. 70 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_repository.dart
  92. 27 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_repository.g.dart
  93. 49 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_state.dart
  94. 105 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_vm.dart
  95. 25 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_vm.g.dart
  96. 124 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_page.dart
  97. 129 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_page.dart
  98. 70 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_repository.dart
  99. 27 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_repository.g.dart
  100. 0 0
      packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_state.dart

+ 1 - 1
app/lib/modules/splash/vm/splash_view_model.dart

@@ -49,7 +49,7 @@ class SplashViewModel extends _$SplashViewModel {
 
     UserConfigService.getInstance();
 
-    if (UserConfigService.getState().haslogin == true) {
+    if (UserConfigService.getState().hasLogin == true) {
       Log.d("已经登录,去首页页面");
       ComponentServiceManager().mainService.startMainPage();
     } else {

+ 1 - 2
packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.dart

@@ -22,7 +22,6 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
   @override
   LoginState build() {
     authRepository = ref.read(authRepositoryProvider);
-
     final state = LoginState();
     initListener(state);
     ref.onDispose(() {
@@ -67,7 +66,7 @@ class AuthLoginViewModel extends _$AuthLoginViewModel {
 
     //请求成功去首页
     if (result.isSuccess) {
-      UserConfigService.getInstance().setToken(result.data?.token);
+      UserConfigService.getInstance().setToken(token: result.data?.token, userName: result.data?.name);
       ComponentServiceManager().mainService.startMainPage();
     } else {
       ToastEngine.show(result.errorMsg ?? "UnKnow Error");

+ 1 - 1
packages/cpt_auth/lib/modules/auth_login/auth_login_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'auth_login_view_model.dart';
 // **************************************************************************
 
 String _$authLoginViewModelHash() =>
-    r'afff62eb84d983159db7ca8c4d7b1a9dde73ce08';
+    r'a3e88f9aa351b658190e033c598003af7c274212';
 
 /// See also [AuthLoginViewModel].
 @ProviderFor(AuthLoginViewModel)

+ 117 - 0
packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_page.dart

@@ -0,0 +1,117 @@
+import 'package:cpt_auth/modules/sing_up_success/sign_up_success_view_model.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/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:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import '../../router/page/auth_page_router.dart';
+import 'estate_upload_success_view_model.dart';
+
+@RoutePage()
+class EstateUploadSuccessPage extends HookConsumerWidget {
+  const EstateUploadSuccessPage({Key? key}) : super(key: key);
+
+  //登录页面进入
+  static void startPop2Login() {
+    appRouter.pushAndPopUntil(
+      const EstateUploadSuccessPageRoute(),
+      predicate: (route) {
+        return route.settings.name == "AuthLoginPageRoute";
+      },
+    );
+  }
+
+  //Me页面进入
+  static void startPop2Estate() {
+    appRouter.pushAndPopUntil(
+      const EstateUploadSuccessPageRoute(),
+      predicate: (route) {
+        return route.settings.name == "MyEstatePageRoute";
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(estateUploadSuccessViewModelProvider.notifier);
+    final userConfig = UserConfigService.getState(ref: ref);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, ""),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Container(
+        padding: const EdgeInsets.symmetric(horizontal: 18),
+        width: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.max,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            SingleChildScrollView(
+                scrollDirection: Axis.vertical,
+                physics: const BouncingScrollPhysics(),
+                child: Column(
+                  children: [
+                    //顶部图片
+                    const MyAssetImage(
+                      Assets.authYyHomeSuccess,
+                      width: 264,
+                      height: 180,
+                    ).alignCenter().marginOnly(top: 12),
+
+                    MyTextView(
+                      S.current.thank_you_name(userConfig.userName ?? ""),
+                      fontSize: 23,
+                      marginTop: 30,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+
+                    MyTextView(
+                      S.current.estate_upload_success_desc,
+                      fontSize: 15,
+                      marginTop: 25,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                )).expanded(),
+            Row(
+              children: [
+                MyButton(
+                  onPressed: viewModel.callEmail,
+                  text: S.current.send_email,
+                  textColor: Colors.white,
+                  backgroundColor: context.appColors.btnBgDefault,
+                  fontWeight: FontWeight.w500,
+                  type: ClickType.throttle,
+                  fontSize: 16,
+                  minHeight: 50,
+                  radius: 5,
+                ).expanded(),
+                MyButton(
+                  onPressed: viewModel.callPhone,
+                  text: S.current.call_phone,
+                  textColor: Colors.white,
+                  backgroundColor: context.appColors.btnBgDefault,
+                  fontWeight: FontWeight.w500,
+                  type: ClickType.throttle,
+                  fontSize: 16,
+                  minHeight: 50,
+                  radius: 5,
+                ).marginOnly(left: 10).expanded(),
+              ],
+            ).marginOnly(top: 50, bottom: 50, left: 18, right: 18),
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 22 - 0
packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_view_model.dart

@@ -0,0 +1,22 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import '../select_estate/select_estate_page.dart';
+
+part 'estate_upload_success_view_model.g.dart';
+
+@riverpod
+class EstateUploadSuccessViewModel extends _$EstateUploadSuccessViewModel {
+  @override
+  void build() {}
+
+  //拨打电话
+  void callPhone() {
+
+  }
+
+  //发送邮件
+  void callEmail() {
+
+  }
+
+}

+ 27 - 0
packages/cpt_auth/lib/modules/estate_upload_success/estate_upload_success_view_model.g.dart

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

+ 5 - 18
packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.dart

@@ -38,25 +38,12 @@ class ForgotInputViewModel extends _$ForgotInputViewModel {
 
     Log.d('当前待提交的 邮箱:${email} 电话:${phone}');
 
-    // if (Utils.isEmpty(email)) {
-    //   state = state.copyWith(emailErrorText: "Email cannot be empty!");
-    //   return;
-    // }
-    //
-    // if (Utils.isEmpty(phone)) {
-    //   state = state.copyWith(phoneErrorText: "Phone cannot be empty!");
-    //   return;
-    // }
+    if (Utils.isEmpty(phone)) {
+      state = state.copyWith(phoneErrorText: "Phone cannot be empty!");
+      return;
+    }
 
-    //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 邮箱:${email} 电话:${phone}');
-
-    gotoForgotVerifyPage();
-  }
-
-  //去忘记密码验证页面
-  void gotoForgotVerifyPage() {
-    ForgotVerifyPage.startInstance();
+    ForgotVerifyPage.startInstance(phone: phone);
   }
 
   //初始化监听

+ 1 - 1
packages/cpt_auth/lib/modules/forgot_input/forgot_input_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'forgot_input_view_model.dart';
 // **************************************************************************
 
 String _$forgotInputViewModelHash() =>
-    r'5998f4831003ebb7e6ebe822bc002580f13b1962';
+    r'd3f941cb656ba085b920cfb68cc80c597e5b97f1';
 
 /// See also [ForgotInputViewModel].
 @ProviderFor(ForgotInputViewModel)

+ 14 - 9
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_page.dart

@@ -5,6 +5,7 @@ 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:plugin_basic/constants/app_constant.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
@@ -19,14 +20,16 @@ import 'forgot_verify_view_model.dart';
 
 @RoutePage()
 class ForgotVerifyPage extends HookConsumerWidget {
-  const ForgotVerifyPage({Key? key}) : super(key: key);
+  final String? phone;
+
+  const ForgotVerifyPage({Key? key, required this.phone}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance({BuildContext? context, required String? phone}) {
     if (context != null) {
-      context.router.push(const ForgotVerifyPageRoute());
+      context.router.push(ForgotVerifyPageRoute(phone: phone));
     } else {
-      appRouter.push(const ForgotVerifyPageRoute());
+      appRouter.push(ForgotVerifyPageRoute(phone: phone));
     }
   }
 
@@ -65,7 +68,7 @@ class ForgotVerifyPage extends HookConsumerWidget {
               ),
 
               MyTextView(
-                "+65 88249621",
+                "+${AppConstant.countryCode} ${phone ?? "-"}",
                 fontSize: 23,
                 marginBottom: 23,
                 isFontMedium: true,
@@ -82,13 +85,13 @@ class ForgotVerifyPage extends HookConsumerWidget {
                 errorText: state.codeErrorText,
                 showRightIcon: true,
                 rightWidget: MyTextView(
-                  state.isCounting? "${state.countdownTime} s": S.current.get_code,
+                  state.isCounting ? "${state.countdownTime} s" : S.current.get_code,
                   textAlign: TextAlign.center,
                   textColor: context.appColors.textPrimary,
                   fontSize: 15,
                   paddingRight: 5,
                   isFontMedium: true,
-                  onClick: state.isCounting ? null : () => viewModel.showVerifyCodedDialog(),
+                  onClick: state.isCounting ? null : () => viewModel.showVerifyCodedDialog(phone),
                 ).paddingOnly(top: 15, bottom: 15),
                 onSubmit: (formKey, value) {
                   state.formData[formKey]!['focusNode'].unfocus();
@@ -159,12 +162,14 @@ class ForgotVerifyPage extends HookConsumerWidget {
                 ),
                 onSubmit: (formKey, value) {
                   state.formData[formKey]!['focusNode'].unfocus();
-                  viewModel.submitVerify();
+                  viewModel.submitVerify(phone);
                 },
               ),
 
               MyButton(
-                onPressed: viewModel.submitVerify,
+                onPressed: (){
+                  viewModel.submitVerify(phone);
+                },
                 text: S.current.next,
                 textColor: Colors.white,
                 backgroundColor: context.appColors.btnBgDefault,

+ 69 - 8
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.dart

@@ -1,7 +1,14 @@
 import 'dart:async';
 
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
@@ -12,21 +19,32 @@ import 'forgot_verify_state.dart';
 part 'forgot_verify_view_model.g.dart';
 
 @riverpod
-class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
+class ForgotVerifyViewModel extends _$ForgotVerifyViewModel with DioCancelableMixin {
+  late final AuthRepository _authRepository;
+
   @override
   ForgotVerifyState build() {
+    _authRepository = ref.read(authRepositoryProvider);
+
     final state = ForgotVerifyState();
     initListener(state);
-    ref.onDispose(() {
+
+    registerCancellation(callback: () {
       onDispose(state);
     });
+
     return state;
   }
 
   //提交重置密码的校验
-  void submitVerify() {
+  void submitVerify(String? phone) async {
     state = state.copyWith(codeErrorText: null, passwordErrorText: null, confirmPasswordErrorText: null);
 
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
     final FocusNode codeFocusNode = state.formData['code']!['focusNode'];
     final FocusNode passwordFocusNode = state.formData['password']!['focusNode'];
     final FocusNode confirmPasswordFocusNode = state.formData['confirm_password']!['focusNode'];
@@ -66,9 +84,21 @@ class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 code:$code password:$password confirmPassword:$confirmPassword');
-
-    gotoLoginPage();
+    final result = await _authRepository.forgotPassword(
+      smsCode: code,
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      password: password,
+      confirmPassword: confirmPassword,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.successful);
+      gotoLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //去登录页面
@@ -86,8 +116,39 @@ class ForgotVerifyViewModel extends _$ForgotVerifyViewModel {
   }
 
   // 验证弹窗
-  void showVerifyCodedDialog() {
-    _startCountDown();
+  showVerifyCodedDialog(String? phone) {
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
+    DialogEngine.show(
+      onDismiss: () {},
+      widget: VerifyCodeDialog(
+        confirmAction: (key, code) {
+          //发送短信验证码
+          sendSMS(phone!, key, code);
+        },
+      ),
+    );
+  }
+
+  /// 调用接口发送短信验证码
+  void sendSMS(String phone, String? key, String? code) async {
+    final result = await _authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   Timer? countdownTimer;

+ 1 - 1
packages/cpt_auth/lib/modules/forgot_verify/forgot_verify_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'forgot_verify_view_model.dart';
 // **************************************************************************
 
 String _$forgotVerifyViewModelHash() =>
-    r'9ca96e6da48e893d90ed8b0dc939ebae4c1fb940';
+    r'8b8ca850496d1176fa0eb77104d3fedf026e3bc3';
 
 /// See also [ForgotVerifyViewModel].
 @ProviderFor(ForgotVerifyViewModel)

+ 61 - 0
packages/cpt_auth/lib/modules/select_estate/attach_input_widget.dart

@@ -0,0 +1,61 @@
+import 'package:cpt_auth/modules/select_estate/select_estate_view_model.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/widget_export.dart';
+
+//输入框的布局,单独抽取为了做Attach弹窗
+class AttachInputWidget extends HookConsumerWidget {
+  final void Function(BuildContext context, String value) onChanged;
+
+  AttachInputWidget({
+    required this.onChanged,
+  });
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(selectEstateViewModelProvider);
+
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        "estate",
+        key: key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        "",
+        hintText: state.formData['estate']!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData['estate']!['controller'],
+        focusNode: state.formData['estate']!['focusNode'],
+        margin: const EdgeInsets.only(top: 0),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        inputType: TextInputType.text,
+        textInputAction: TextInputAction.done,
+        onChanged: (k, v) {
+          onChanged.call(context, v);
+        },
+        changeActionType: ClickType.debounce,
+        changeActionMilliseconds: 500,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: false,
+        errorText: null,
+        showLeftIcon: true,
+        showRightIcon: false,
+        rightWidget: null,
+      ),
+    );
+  }
+}

+ 74 - 0
packages/cpt_auth/lib/modules/select_estate/dialog/attach_search_dialog.dart

@@ -0,0 +1,74 @@
+import 'package:cpt_auth/modules/auth_login/auth_login_page.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.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/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../select_estate_view_model.dart';
+
+//输入文本框
+class AttachSearchDialog extends HookConsumerWidget {
+  final ValueChanged<IdNameEntity?> onSelected;
+
+  AttachSearchDialog({
+    required this.onSelected,
+  });
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(selectEstateViewModelProvider);
+
+    return Container(
+      margin: const EdgeInsets.symmetric(horizontal: 38),
+      padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteBG,
+        borderRadius: BorderRadius.circular(5.0), // 5个圆角
+        boxShadow: [
+          BoxShadow(
+            color: const Color(0xFF656565).withOpacity(0.1), // 阴影颜色,并且设置透明度
+            offset: const Offset(0, 1.5), // 阴影的偏移量
+            blurRadius: 2.5, // 模糊半径
+            spreadRadius: 1.5, // 扩散半径
+          ),
+        ],
+      ),
+      constraints: const BoxConstraints(
+        maxHeight: 200, // 设置最大高度
+      ),
+      child: ListView.builder(
+        padding: EdgeInsets.zero,
+        shrinkWrap: true,
+        physics: const AlwaysScrollableScrollPhysics(),
+        itemCount: state.estateList?.length ?? 0,
+        itemBuilder: (context, index) {
+          final item = state.estateList?[index];
+          return MyTextView(
+            item?.name ?? "",
+            fontSize: 15,
+            paddingTop: 10,
+            paddingBottom: 10,
+            isFontRegular: true,
+            onClick: () {
+              onSelected(item); // 选中回调
+              onCancel();
+            },
+            textColor: context.appColors.textBlack,
+          );
+        },
+      ),
+    );
+  }
+}
+
+//取消弹框
+void onCancel() async {
+  SmartDialog.dismiss();
+}

+ 128 - 114
packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart

@@ -1,24 +1,31 @@
-import 'package:cpt_auth/modules/select_estate/select_estate_state.dart';
+import 'dart:async';
 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:shared/utils/log_utils.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_field.dart';
 import 'package:widgets/my_text_view.dart';
-import 'package:widgets/widget_export.dart';
-
+import 'package:plugin_basic/basic_export.dart';
 import '../../router/page/auth_page_router.dart';
+import 'attach_input_widget.dart';
 import 'select_estate_view_model.dart';
 
 @RoutePage()
-class SelectEstatePage extends HookConsumerWidget {
+class SelectEstatePage extends HookConsumerWidget with WidgetsBindingObserver {
+  SelectEstateViewModel? viewModel;
+  bool _isKeyboardVisible = false; //软件是否展示
+  double _previousBottom = 0; // 用于保存上一个 Insets
+  Function()? throttledShowDropDownDialog; // 定义防抖函数
+  bool isVisible = true; //页面是否可见
+
   SelectEstatePage({Key? key}) : super(key: key);
 
   //启动当前页面
@@ -32,127 +39,134 @@ class SelectEstatePage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final viewModel = ref.watch(selectEstateViewModelProvider.notifier);
+    viewModel = ref.watch(selectEstateViewModelProvider.notifier);
     final state = ref.watch(selectEstateViewModelProvider);
 
+    // 初始化防抖函数
+    throttledShowDropDownDialog ??= throttle(() {
+      viewModel?.showDropDownDialog(needReLocation: true);
+    }) as Function()?;
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      WidgetsBinding.instance.addObserver(this);
+      return () {
+        // 组件卸载时执行
+        WidgetsBinding.instance.removeObserver(this);
+      };
+    }, []);
+
     return Scaffold(
       appBar: MyAppBar.appBar(context, S.current.yy_home_accounts),
       backgroundColor: context.appColors.backgroundDefault,
       body: Container(
         padding: const EdgeInsets.symmetric(horizontal: 38),
         width: double.infinity,
-        child: Column(
-          mainAxisSize: MainAxisSize.max,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          children: [
-            SingleChildScrollView(
-                scrollDirection: Axis.vertical,
-                physics: const BouncingScrollPhysics(),
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.center,
-                  children: [
-                    //顶部图片
-                    const MyAssetImage(
-                      Assets.authChooseEstateBuilding,
-                      width: 267,
-                      height: 158,
-                    ).marginOnly(top: 28, bottom: 38),
-
-                    MyTextView(
-                      S.current.estate_or_building_name,
-                      fontSize: 23,
-                      marginBottom: 20,
-                      textAlign: TextAlign.center,
-                      isFontMedium: true,
-                      textColor: context.appColors.textBlack,
-                    ),
-
-                    //输入资产的名称
-                    _buildInputLayout(
-                      context,
-                      state,
-                      "estate",
-                      textInputAction: TextInputAction.done,
-                      onSubmit: (formKey, value) {
-                        state.formData[formKey]!['focusNode'].unfocus();
-                      },
-                    ),
-
-                    MyTextView(
-                      S.current.estate_name_desc,
-                      fontSize: 15,
-                      marginTop: 19,
-                      isFontMedium: true,
-                      textColor: context.appColors.textBlack,
-                    ),
-                  ],
-                )).expanded(),
-
-            MyButton(
-              onPressed: viewModel.submitEstate,
-              text: S.current.next,
-              textColor: Colors.white,
-              backgroundColor: context.appColors.btnBgDefault,
-              fontWeight: FontWeight.w500,
-              type: ClickType.throttle,
-              fontSize: 16,
-              minHeight: 50,
-              radius: 5,
-            ).marginOnly(top: 50, bottom: 50),
-          ],
+        child: VisibilityDetector(
+          key: Key('select-estate-page'),
+          onVisibilityChanged: (VisibilityInfo info) {
+            // 检测页面是否可见
+            isVisible = info.visibleFraction > 0;
+            Log.d("检测页面是否可见:$isVisible");
+          },
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              SingleChildScrollView(
+                  scrollDirection: Axis.vertical,
+                  physics: const BouncingScrollPhysics(),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    children: [
+                      //顶部图片
+                      const MyAssetImage(
+                        Assets.authChooseEstateBuilding,
+                        width: 267,
+                        height: 158,
+                      ).marginOnly(top: 28, bottom: 38),
+
+                      MyTextView(
+                        S.current.estate_or_building_name,
+                        fontSize: 23,
+                        marginBottom: 20,
+                        textAlign: TextAlign.center,
+                        isFontMedium: true,
+                        textColor: context.appColors.textBlack,
+                      ),
+
+                      //输入资产的名称
+                      AttachInputWidget(
+                        onChanged: (context, value) {
+                          viewModel?.searchEstate(context, value);
+                        },
+                      ),
+
+                      MyTextView(
+                        S.current.estate_name_desc,
+                        fontSize: 15,
+                        marginTop: 19,
+                        isFontMedium: true,
+                        textColor: context.appColors.textBlack,
+                      ),
+                    ],
+                  )).expanded(),
+              MyButton(
+                onPressed: (){
+                  isVisible = false;
+                  viewModel?.submitEstate();
+                },
+                text: S.current.next,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 50, bottom: 50),
+            ],
+          ),
         ),
       ),
     );
   }
 
-  /// 输入框
-  Widget _buildInputLayout(
-    BuildContext context,
-    SelectEstateState state,
-    String formKey, {
-    Key? key,
-    double marginTop = 0,
-    bool? showRightIcon = false, //是否展示右侧的布局
-    Widget? rightWidget, //右侧的布局
-    TextInputType textInputType = TextInputType.text,
-    String? errorText,
-    bool obscureText = false,
-    TextInputAction textInputAction = TextInputAction.done,
-    Function? onSubmit,
-  }) {
-    return IgnoreKeyboardDismiss(
-      child: MyTextField(
-        formKey,
-        key: key,
-        fillBackgroundColor: context.appColors.authFiledBG,
-        state.formData[formKey]!['value'],
-        hintText: state.formData[formKey]!['hintText'],
-        hintStyle: TextStyle(
-          color: context.appColors.authFiledHint,
-          fontSize: 16.0,
-          fontWeight: FontWeight.w500,
-        ),
-        controller: state.formData[formKey]!['controller'],
-        focusNode: state.formData[formKey]!['focusNode'],
-        margin: EdgeInsets.only(top: marginTop),
-        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
-        showDivider: false,
-        height: 44,
-        style: TextStyle(
-          color: context.appColors.authFiledText,
-          fontSize: 16.0,
-          fontWeight: FontWeight.w500,
-        ),
-        inputType: textInputType,
-        textInputAction: textInputAction,
-        onSubmit: onSubmit,
-        cursorColor: context.appColors.authFiledText,
-        obscureText: obscureText,
-        errorText: errorText,
-        showLeftIcon: true,
-        showRightIcon: showRightIcon,
-        rightWidget: rightWidget,
-      ),
-    );
+  @override
+  void didChangeMetrics() {
+    //页面不可见时不走逻辑
+    if (!isVisible) return;
+
+    // 当键盘弹出或收起时,这里会被调用
+    final currentInsets = WidgetsBinding.instance.window.viewInsets;
+
+    if (currentInsets.bottom > 0 && _previousBottom == 0) {
+      //键盘已弹出
+      _isKeyboardVisible = true;
+    } else if (currentInsets.bottom == 0 && _previousBottom > 0) {
+      //键盘已收起
+      _isKeyboardVisible = false;
+
+      //软键盘收起的时候,重新布局Attach下拉选弹窗
+      throttledShowDropDownDialog?.call();
+    }
+
+    // 更新上一个 Insets
+    _previousBottom = currentInsets.bottom;
+  }
+
+  //防抖 throttle 函数
+  Function throttle(void Function() callback, [int milliseconds = 500]) {
+    bool _isAllowed = true;
+    Timer? _throttleTimer;
+    return () {
+      if (!_isAllowed) return;
+      _isAllowed = false;
+      callback();
+      _throttleTimer?.cancel();
+      _throttleTimer = Timer(Duration(milliseconds: milliseconds), () {
+        _isAllowed = true;
+      });
+    };
   }
 }

+ 29 - 3
packages/cpt_auth/lib/modules/select_estate/select_estate_state.dart

@@ -1,16 +1,30 @@
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/id_name_entity.dart';
 import 'package:flutter/material.dart';
 
 class SelectEstateState {
   //表单的校验与数据
   final Map<String, Map<String, dynamic>> formData;
 
-  double remainingSpace;
+  List<IdNameEntity>? estateList;  //第一步的下拉选房产数据源
+
+  IdNameEntity? selectedEstate; //第一步数据:已经选中的房产
+
+  String? block; //第二步数据:已经选中的Block
+  String? unit; //第二步数据:已经选中的单元
+  String? room; //第二步数据:已经选中的单元-房间
+
+  String? type; //第三步数据:已经选中的类型
 
   // ===================================  Begin  ↓  ===================================
 
   SelectEstateState({
-    this.remainingSpace = 0,
+    this.estateList,
+    this.selectedEstate,
+    this.block,
+    this.unit,
+    this.room,
+    this.type,
     Map<String, Map<String, dynamic>>? formData,
   }) : formData = formData ??
             {
@@ -25,9 +39,21 @@ class SelectEstateState {
 
   SelectEstateState copyWith({
     double? remainingSpace,
+    List<IdNameEntity>? estateList,
+    IdNameEntity? selectedEstate,
+    String? block,
+    String? unit,
+    String? room,
+    String? type,
   }) {
     return SelectEstateState(
-      remainingSpace: remainingSpace ?? this.remainingSpace,
+      estateList: estateList ?? this.estateList,
+      selectedEstate: selectedEstate ?? this.selectedEstate,
+      block: block ?? this.block,
+      unit: unit ?? this.unit,
+      room: room ?? this.room,
+      type: type ?? this.type,
+      formData: this.formData,
     );
   }
 }

+ 74 - 4
packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.dart

@@ -1,21 +1,91 @@
-
 import 'package:cpt_auth/modules/select_estate/select_estate_state.dart';
 import 'package:cpt_auth/modules/select_unit/select_unit_page.dart';
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/repository/profile_repository.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+
+import 'dialog/attach_search_dialog.dart';
 
 part 'select_estate_view_model.g.dart';
 
 @riverpod
-class SelectEstateViewModel extends _$SelectEstateViewModel {
+class SelectEstateViewModel extends _$SelectEstateViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+  BuildContext? _targetContext;
 
   @override
-  SelectEstateState build(){
-    return SelectEstateState();
+  SelectEstateState build() {
+    _profileRepository = ref.read(profileRepositoryProvider);
+    final state = SelectEstateState();
+    registerCancellation();
+    return state;
   }
 
   /// 提交并进入下一步
   void submitEstate() {
+    if (state.selectedEstate == null) {
+      ToastEngine.show("Select Estate First");
+      return;
+    }
+
     SelectUnitPage.startInstance();
   }
 
+  /// 关键字搜索房产
+  void searchEstate(BuildContext targetContext, String? keyword) async {
+    _targetContext = targetContext;
+    final result = await _profileRepository.searchEstate(keyword: keyword, cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      final list = result.list;
+
+      if (list != null && list.isNotEmpty) {
+        state = state.copyWith(estateList: list);
+        //尝试展示下拉选选项
+        showDropDownDialog();
+      }
+    } else {
+      Log.e(result.errorMsg ?? "UnKnow Error");
+    }
+  }
+
+  //Attach下拉选
+  void showDropDownDialog({bool needReLocation = false}) {
+    if (_targetContext == null) return;
+    if (state.estateList == null || state.estateList!.isEmpty) return;
+
+    if (needReLocation) {
+      Log.d("需要重新定位弹出");
+      DialogEngine.dismiss(tag: 'estate');
+    }
+    if (!DialogEngine.checkIsExist(tag: 'estate') || needReLocation) {
+      DialogEngine.showAttach(
+        tag: 'estate',
+        targetContext: _targetContext!,
+        position: DialogPosition.bottom,
+        widget: AttachSearchDialog(
+          onSelected: (item) {
+            state = state.copyWith(selectedEstate: item);
+            final TextEditingController controller = state.formData['estate']!['controller'];
+            controller.text = item?.name ?? "";
+          },
+        ),
+      );
+    }
+  }
+
+  /// 保存第二步的单元等信息
+  void saveUnit({required String block, required String unit, required String room}) {
+    state = state.copyWith(block: block, unit: unit, room: room);
+  }
+
+  /// 保存第三步的角色信息
+  void saveRoleType({required String type}) {
+    state = state.copyWith(type: type);
+  }
 }

+ 1 - 1
packages/cpt_auth/lib/modules/select_estate/select_estate_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'select_estate_view_model.dart';
 // **************************************************************************
 
 String _$selectEstateViewModelHash() =>
-    r'5f5009ecf893acd0a8814a57432abeab66b05325';
+    r'aba0d6d52228a8b0cdfb7fb1e4fb1009fb33df94';
 
 /// See also [SelectEstateViewModel].
 @ProviderFor(SelectEstateViewModel)

+ 7 - 0
packages/cpt_auth/lib/modules/select_role/select_role_view_model.dart

@@ -2,17 +2,24 @@ import 'package:cpt_auth/modules/select_role/select_role_state.dart';
 import 'package:cpt_auth/modules/tenant_doc/tenant_doc_page.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
+import '../select_estate/select_estate_state.dart';
+import '../select_estate/select_estate_view_model.dart';
+
 part 'select_role_view_model.g.dart';
 
 @riverpod
 class SelectRoleViewModel extends _$SelectRoleViewModel {
+  late final SelectEstateViewModel _selectEstateViewModel;
+
   @override
   SelectRoleState build() {
+    _selectEstateViewModel = ref.watch(selectEstateViewModelProvider.notifier);
     return SelectRoleState();
   }
 
   //进入下一步
   void submitRole() {
+    _selectEstateViewModel.saveRoleType(type: "${state.selectedIndex + 1}");
     TenantDocPage.startInstance();
   }
 

+ 1 - 1
packages/cpt_auth/lib/modules/select_role/select_role_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'select_role_view_model.dart';
 // **************************************************************************
 
 String _$selectRoleViewModelHash() =>
-    r'a42d4ba4dd03754e74e58b1a320793449326bef4';
+    r'dcf0c9060d9661a5428df0fa2136cc138dc6050d';
 
 /// See also [SelectRoleViewModel].
 @ProviderFor(SelectRoleViewModel)

+ 9 - 5
packages/cpt_auth/lib/modules/select_unit/select_unit_page.dart

@@ -1,6 +1,7 @@
 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:domain/entity/id_name_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -21,14 +22,15 @@ import 'select_unit_view_model.dart';
 
 @RoutePage()
 class SelectUnitPage extends HookConsumerWidget {
-  SelectUnitPage({Key? key}) : super(key: key);
+
+  const SelectUnitPage({Key? key,}) : super(key: key);
 
   //启动当前页面
   static void startInstance({BuildContext? context}) {
     if (context != null) {
-      context.router.push(SelectUnitPageRoute());
+      context.router.push(const SelectUnitPageRoute());
     } else {
-      appRouter.push(SelectUnitPageRoute());
+      appRouter.push(const SelectUnitPageRoute());
     }
   }
 
@@ -80,6 +82,7 @@ class SelectUnitPage extends HookConsumerWidget {
                               context,
                               state,
                               "block",
+                              textInputType: TextInputType.text,
                               textInputAction: TextInputAction.next,
                               onSubmit: (formKey, value) {
                                 state.formData[formKey]!['focusNode'].unfocus();
@@ -177,9 +180,10 @@ class SelectUnitPage extends HookConsumerWidget {
                     ),
                   ],
                 )).expanded(),
-
             MyButton(
-              onPressed: viewModel.submitUnit,
+              onPressed: (){
+                viewModel.submitUnit();
+              },
               text: S.current.next,
               textColor: Colors.white,
               backgroundColor: context.appColors.btnBgDefault,

+ 0 - 12
packages/cpt_auth/lib/modules/select_unit/select_unit_state.dart

@@ -4,12 +4,9 @@ class SelectUnitState {
   //表单的校验与数据
   final Map<String, Map<String, dynamic>> formData;
 
-  double remainingSpace;
-
   // ===================================  Begin  ↓  ===================================
 
   SelectUnitState({
-    this.remainingSpace = 0,
     Map<String, Map<String, dynamic>>? formData,
   }) : formData = formData ??
             {
@@ -35,13 +32,4 @@ class SelectUnitState {
                 'obsecure': false,
               },
             };
-
-  SelectUnitState copyWith({
-    double? remainingSpace,
-  }) {
-    return SelectUnitState(
-      remainingSpace: remainingSpace ?? this.remainingSpace,
-    );
-  }
-
 }

+ 60 - 5
packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.dart

@@ -1,20 +1,75 @@
+import 'package:cpt_auth/modules/select_estate/select_estate_view_model.dart';
 import 'package:cpt_auth/modules/select_role/select_role_page.dart';
 import 'package:cpt_auth/modules/select_unit/select_unit_state.dart';
+import 'package:domain/repository/profile_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import '../select_estate/select_estate_state.dart';
 
 part 'select_unit_view_model.g.dart';
 
 @riverpod
-class SelectUnitViewModel extends _$SelectUnitViewModel {
+class SelectUnitViewModel extends _$SelectUnitViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+  late final SelectEstateViewModel _selectEstateViewModel;
+  late final SelectEstateState _selectEstateState;
 
   @override
   SelectUnitState build() {
-    return SelectUnitState();
+    _profileRepository = ref.read(profileRepositoryProvider);
+    _selectEstateViewModel = ref.watch(selectEstateViewModelProvider.notifier);
+    _selectEstateState = ref.watch(selectEstateViewModelProvider);
+
+    final state = SelectUnitState();
+    registerCancellation();
+    return state;
   }
 
   /// 提交选择的街道与单元
-  void submitUnit() {
-    SelectRolePage.startInstance();
-  }
+  void submitUnit() async {
+    final FocusNode blockFocusNode = state.formData['block']!['focusNode'];
+    final FocusNode unitFocusNode = state.formData['unit']!['focusNode'];
+    final FocusNode roomFocusNode = state.formData['room']!['focusNode'];
+
+    blockFocusNode.unfocus();
+    unitFocusNode.unfocus();
+    roomFocusNode.unfocus();
+
+    final TextEditingController blockController = state.formData['block']!['controller'];
+    final TextEditingController unitController = state.formData['unit']!['controller'];
+    final TextEditingController roomController = state.formData['room']!['controller'];
+
+    final block = blockController.text;
+    final unit = unitController.text;
+    final room = roomController.text;
 
+    if (Utils.isEmpty(block)) {
+      ToastEngine.show("Block cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(unit)) {
+      ToastEngine.show("Unit Number cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(room)) {
+      ToastEngine.show("Unit Number cannot be empty!");
+      return;
+    }
+
+    final result = await _profileRepository.estateJoinCheck(estateId: _selectEstateState.selectedEstate?.id, block: block, unit: "$unit-$room");
+
+    if (result.isSuccess) {
+      //存入内存数据
+      _selectEstateViewModel.saveUnit(block: block, unit: unit, room: room);
+      SelectRolePage.startInstance();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
 }

+ 1 - 1
packages/cpt_auth/lib/modules/select_unit/select_unit_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'select_unit_view_model.dart';
 // **************************************************************************
 
 String _$selectUnitViewModelHash() =>
-    r'f4f8001a0fa6e406b06fe7a8ecaba8e6309e21c5';
+    r'04669c8553c295069d6cc1fb0f7e771cbbc72672';
 
 /// See also [SelectUnitViewModel].
 @ProviderFor(SelectUnitViewModel)

+ 0 - 2
packages/cpt_auth/lib/modules/sign_up/sign_up_view_model.dart

@@ -120,10 +120,8 @@ class SignUpViewModel extends _$SignUpViewModel {
       ),
     );
 
-
   }
 
-
   //切换隐藏显示密码
   void switchPwdVisibility() {
     state = state.copyWith(pwdVisibility: !state.pwdVisibility);

+ 5 - 4
packages/cpt_auth/lib/modules/sing_up_success/sign_up_success_page.dart

@@ -5,6 +5,7 @@ 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:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
@@ -18,11 +19,11 @@ class SignUpSuccessPage extends HookConsumerWidget {
   const SignUpSuccessPage({Key? key}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance() {
     appRouter.pushAndPopUntil(
       const SignUpSuccessPageRoute(),
       predicate: (route) {
-        return route.settings.name == 'AuthLoginPageRoute';
+        return route.settings.name == AuthLoginPageRoute.name;
       },
     );
   }
@@ -30,6 +31,7 @@ class SignUpSuccessPage extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.watch(signUpSuccessViewModelProvider.notifier);
+    final userConfig = UserConfigService.getState(ref: ref);
 
     return Scaffold(
       appBar: MyAppBar.appBar(context, ""),
@@ -54,7 +56,7 @@ class SignUpSuccessPage extends HookConsumerWidget {
                     ).alignCenter().marginOnly(top: 12),
 
                     MyTextView(
-                      S.current.welcome_name("Huyu"),
+                      S.current.welcome_name(userConfig.userName ?? ""),
                       fontSize: 23,
                       marginTop: 30,
                       isFontMedium: true,
@@ -86,7 +88,6 @@ class SignUpSuccessPage extends HookConsumerWidget {
                     ),
                   ],
                 )).expanded(),
-
             MyButton(
               onPressed: viewModel.gotoSelectEstatePage,
               text: S.current.get_started,

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

@@ -1,4 +1,3 @@
-import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
 import '../select_estate/select_estate_page.dart';

+ 1 - 1
packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.dart

@@ -61,7 +61,7 @@ class SignUpVerifyViewModel extends _$SignUpVerifyViewModel {
     if (result.isSuccess) {
       NotifyEngine.showSuccess(S.current.successful);
       //存入Token
-      UserConfigService.getInstance().setToken(result.data?.token);
+      UserConfigService.getInstance().setToken(token: result.data?.token, userName: result.data?.name);
       //去成功页面
       SignUpSuccessPage.startInstance();
     } else {

+ 1 - 1
packages/cpt_auth/lib/modules/sing_up_verify/sign_up_verify_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'sign_up_verify_view_model.dart';
 // **************************************************************************
 
 String _$signUpVerifyViewModelHash() =>
-    r'853c61774b0353652744df67e42d7fefe16f41e7';
+    r'ad1cb9a410068dac7bf1311d777f3fe0baa1a938';
 
 /// See also [SignUpVerifyViewModel].
 @ProviderFor(SignUpVerifyViewModel)

+ 1 - 15
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_page.dart

@@ -60,22 +60,8 @@ class TenantDocPage extends HookConsumerWidget {
                       textColor: context.appColors.textBlack,
                     ),
                     MyTextView(
-                      S.current.upload_doc_desc,
+                      state.type == "1" ? S.current.upload_doc_owner_desc : S.current.upload_doc_tenant_desc,
                       fontSize: 15,
-                      isFontMedium: true,
-                      textColor: context.appColors.textBlack,
-                    ),
-                    MyTextView(
-                      S.current.upload_doc_desc1,
-                      fontSize: 15,
-                      marginTop: 22,
-                      isFontMedium: true,
-                      textColor: context.appColors.textBlack,
-                    ),
-                    MyTextView(
-                      S.current.upload_doc_desc2,
-                      fontSize: 15,
-                      marginTop: 22,
                       marginBottom: 24,
                       isFontMedium: true,
                       textColor: context.appColors.textBlack,

+ 4 - 6
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_state.dart

@@ -1,22 +1,20 @@
 class TenantDocState {
-
   final List<String> docList;
 
-  final double remainingSpace;
+  final String type;
 
   const TenantDocState({
     required this.docList,
-    this.remainingSpace = 0,
+    required this.type,
   });
 
   TenantDocState copyWith({
     List<String>? docList,
-    double? remainingSpace,
+    String? type,
   }) {
     return TenantDocState(
       docList: docList ?? this.docList,
-      remainingSpace: remainingSpace ?? this.remainingSpace,
+      type: type ?? this.type,
     );
   }
-
 }

+ 48 - 7
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.dart

@@ -1,28 +1,69 @@
-
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/profile_repository.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
+import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/log_utils.dart';
 
+import '../estate_upload_success/estate_upload_success_page.dart';
+import '../select_estate/select_estate_state.dart';
+import '../select_estate/select_estate_view_model.dart';
 import 'tenant_doc_state.dart';
 
 part 'tenant_doc_view_model.g.dart';
 
 @riverpod
 class TenantDocViewModel extends _$TenantDocViewModel {
+  late final ProfileRepository _profileRepository;
+  late final SelectEstateState _selectEstateState;
 
   @override
-  TenantDocState build(){
-    return const TenantDocState(docList: []);
+  TenantDocState build() {
+    _profileRepository = ref.read(profileRepositoryProvider);
+    _selectEstateState = ref.watch(selectEstateViewModelProvider);
+
+    return TenantDocState(docList: [], type: _selectEstateState.type ?? "1");
   }
 
   //设置已选中的文件数组
-  void setDocList(List<String> list){
+  void setDocList(List<String> list) {
     state = state.copyWith(docList: list);
   }
 
   //提交文件
-  void submitDoc() {
-    ToastEngine.show("请求接口上传文件:${state.docList}");
-  }
+  void submitDoc() async {
+    if (state.docList.isEmpty) {
+      ToastEngine.show("Select Documents First");
+      return;
+    }
 
+    final result = await _profileRepository.joinEstateUnit(
+      estateId: _selectEstateState.selectedEstate?.id,
+      block: _selectEstateState.block,
+      unit: "${_selectEstateState.unit}-${_selectEstateState.room}",
+      type: _selectEstateState.type,
+      paths: state.docList,
+    );
 
+    if (result.isSuccess) {
+      //如果有用户信息,说明是在Me页面添加的
+      if (UserConfigService.getState().user != null) {
+        //刷新Estate页面
+        bus.emit(AppConstant.eventEstateRefresh, true);
+        //去成功页面
+        Log.d("Estate页面");
+        EstateUploadSuccessPage.startPop2Estate();
+      } else {
+        Log.d("登录页面");
+        //如果没有用户信息,说明是在登录页面添加的。
+        EstateUploadSuccessPage.startPop2Login();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
 }

+ 1 - 1
packages/cpt_auth/lib/modules/tenant_doc/tenant_doc_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'tenant_doc_view_model.dart';
 // **************************************************************************
 
 String _$tenantDocViewModelHash() =>
-    r'8283e1970743d66a871e1145e15ffd3177d3a42b';
+    r'92e8fc2e3d5b1e9f7a709ca06a17adb6a28c76ff';
 
 /// See also [TenantDocViewModel].
 @ProviderFor(TenantDocViewModel)

+ 3 - 0
packages/cpt_auth/lib/router/page/auth_page_router.dart

@@ -1,4 +1,5 @@
 import 'package:auto_route/auto_route.dart';
+import 'package:domain/entity/id_name_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
@@ -13,6 +14,7 @@ import '../../modules/select_estate/select_estate_page.dart';
 import '../../modules/select_unit/select_unit_page.dart';
 import '../../modules/select_role/select_role_page.dart';
 import '../../modules/tenant_doc/tenant_doc_page.dart';
+import '../../modules/estate_upload_success/estate_upload_success_page.dart';
 
 
 
@@ -35,5 +37,6 @@ class AuthPageRouter extends _$AuthPageRouter {
     CustomRoute(page: SelectUnitPageRoute.page, path: RouterPath.authSelectUnit, transitionsBuilder: applySlideTransition),
     CustomRoute(page: SelectRolePageRoute.page, path: RouterPath.authSelectRole, transitionsBuilder: applySlideTransition),
     CustomRoute(page: TenantDocPageRoute.page, path: RouterPath.authTenantDoc, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: EstateUploadSuccessPageRoute.page, path: RouterPath.authEstateUploadSuccess, transitionsBuilder: applySlideTransition),
   ];
 }

+ 58 - 27
packages/cpt_auth/lib/router/page/auth_page_router.gr.dart

@@ -21,6 +21,12 @@ abstract class _$AuthPageRouter extends RootStackRouter {
         child: const AuthLoginPage(),
       );
     },
+    EstateUploadSuccessPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const EstateUploadSuccessPage(),
+      );
+    },
     ForgotInputPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -28,9 +34,13 @@ abstract class _$AuthPageRouter extends RootStackRouter {
       );
     },
     ForgotVerifyPageRoute.name: (routeData) {
+      final args = routeData.argsAs<ForgotVerifyPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: const ForgotVerifyPage(),
+        child: ForgotVerifyPage(
+          key: args.key,
+          phone: args.phone,
+        ),
       );
     },
     SelectEstatePageRoute.name: (routeData) {
@@ -48,11 +58,9 @@ abstract class _$AuthPageRouter extends RootStackRouter {
       );
     },
     SelectUnitPageRoute.name: (routeData) {
-      final args = routeData.argsAs<SelectUnitPageRouteArgs>(
-          orElse: () => const SelectUnitPageRouteArgs());
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: SelectUnitPage(key: args.key),
+        child: const SelectUnitPage(),
       );
     },
     SignUpPageRoute.name: (routeData) {
@@ -110,6 +118,20 @@ class AuthLoginPageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [EstateUploadSuccessPage]
+class EstateUploadSuccessPageRoute extends PageRouteInfo<void> {
+  const EstateUploadSuccessPageRoute({List<PageRouteInfo>? children})
+      : super(
+          EstateUploadSuccessPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'EstateUploadSuccessPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [ForgotInputPage]
 class ForgotInputPageRoute extends PageRouteInfo<void> {
   const ForgotInputPageRoute({List<PageRouteInfo>? children})
@@ -125,16 +147,40 @@ class ForgotInputPageRoute extends PageRouteInfo<void> {
 
 /// generated route for
 /// [ForgotVerifyPage]
-class ForgotVerifyPageRoute extends PageRouteInfo<void> {
-  const ForgotVerifyPageRoute({List<PageRouteInfo>? children})
-      : super(
+class ForgotVerifyPageRoute extends PageRouteInfo<ForgotVerifyPageRouteArgs> {
+  ForgotVerifyPageRoute({
+    Key? key,
+    required String? phone,
+    List<PageRouteInfo>? children,
+  }) : super(
           ForgotVerifyPageRoute.name,
+          args: ForgotVerifyPageRouteArgs(
+            key: key,
+            phone: phone,
+          ),
           initialChildren: children,
         );
 
   static const String name = 'ForgotVerifyPageRoute';
 
-  static const PageInfo<void> page = PageInfo<void>(name);
+  static const PageInfo<ForgotVerifyPageRouteArgs> page =
+      PageInfo<ForgotVerifyPageRouteArgs>(name);
+}
+
+class ForgotVerifyPageRouteArgs {
+  const ForgotVerifyPageRouteArgs({
+    this.key,
+    required this.phone,
+  });
+
+  final Key? key;
+
+  final String? phone;
+
+  @override
+  String toString() {
+    return 'ForgotVerifyPageRouteArgs{key: $key, phone: $phone}';
+  }
 }
 
 /// generated route for
@@ -182,31 +228,16 @@ class SelectRolePageRoute extends PageRouteInfo<void> {
 
 /// generated route for
 /// [SelectUnitPage]
-class SelectUnitPageRoute extends PageRouteInfo<SelectUnitPageRouteArgs> {
-  SelectUnitPageRoute({
-    Key? key,
-    List<PageRouteInfo>? children,
-  }) : super(
+class SelectUnitPageRoute extends PageRouteInfo<void> {
+  const SelectUnitPageRoute({List<PageRouteInfo>? children})
+      : super(
           SelectUnitPageRoute.name,
-          args: SelectUnitPageRouteArgs(key: key),
           initialChildren: children,
         );
 
   static const String name = 'SelectUnitPageRoute';
 
-  static const PageInfo<SelectUnitPageRouteArgs> page =
-      PageInfo<SelectUnitPageRouteArgs>(name);
-}
-
-class SelectUnitPageRouteArgs {
-  const SelectUnitPageRouteArgs({this.key});
-
-  final Key? key;
-
-  @override
-  String toString() {
-    return 'SelectUnitPageRouteArgs{key: $key}';
-  }
+  static const PageInfo<void> page = PageInfo<void>(name);
 }
 
 /// generated route for

+ 68 - 61
packages/cpt_main/lib/modules/me/me_page.dart

@@ -11,6 +11,7 @@ import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/shatter/setting_item_container.dart';
+import 'package:widgets/widget_export.dart';
 
 import 'me_view_model.dart';
 
@@ -34,67 +35,73 @@ class MePage extends HookConsumerWidget {
             : ThemeConfig.systemUiOverlayStyleLightThemeWhite,
       ),
       backgroundColor: context.appColors.backgroundDark,
-      body: SingleChildScrollView(
-        scrollDirection: Axis.vertical,
-        physics: const BouncingScrollPhysics(),
-        child: SizedBox(
-          width: double.infinity,
-          child: Column(
-            mainAxisSize: MainAxisSize.max,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              //顶部信息
-              _buildTopProfile(context, ref),
-
-              //关注与粉丝
-              _buildFollower(context, ref),
-
-              //我的发布
-              SettingItemContainer(
-                title: S.current.my_post,
-                iconPath: Assets.mainMeMyPostIcon,
-                isShowMoreIcon: true,
-                rightWidget: MyTextView(
-                  userConfig.user?.postsCount ?? "0",
-                  textColor: context.appColors.textPrimary,
-                  fontSize: 20,
-                  isFontMedium: true,
-                ),
-              ).onTap(viewModel.gotoMyPostPage).marginOnly(top: 10),
-
-              //家庭
-              SettingItemContainer(
-                title: S.current.household,
-                iconPath: Assets.mainMeHouseholdIcon,
-                isShowMoreIcon: true,
-                rightWidget: MyTextView(
-                  userConfig.user?.households?.length.toString() ?? "0",
-                  textColor: context.appColors.textPrimary,
-                  fontSize: 20,
-                  isFontMedium: true,
-                ),
-              ).onTap(viewModel.gotoMyHouseholdPage),
-
-              //房产
-              SettingItemContainer(
-                title: S.current.estate,
-                iconPath: Assets.mainMeEstateIcon,
-                isShowMoreIcon: true,
-                rightWidget: MyTextView(
-                  userConfig.user?.estates?.length.toString() ?? "0",
-                  textColor: context.appColors.textPrimary,
-                  fontSize: 20,
-                  isFontMedium: true,
-                ),
-              ).onTap(viewModel.gotoMyEstatePage),
-
-              //设置
-              SettingItemContainer(
-                title: S.current.settings,
-                iconPath: Assets.mainMeSettingIcon,
-                isShowMoreIcon: true,
-              ).onTap(viewModel.gotoSettingPage),
-            ],
+      body: EasyRefresh(
+        controller: viewModel.refreshController,
+        header: const MaterialHeader(),
+        onRefresh: viewModel.onRefresh,
+        child: SingleChildScrollView(
+          scrollDirection: Axis.vertical,
+          child: SizedBox(
+            width: double.infinity,
+            child: Column(
+              mainAxisSize: MainAxisSize.max,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                //顶部信息
+                _buildTopProfile(context, ref),
+
+                //关注与粉丝
+                _buildFollower(context, ref),
+
+                //我的发布
+                SettingItemContainer(
+                  title: S.current.my_post,
+                  iconPath: Assets.mainMeMyPostIcon,
+                  isShowMoreIcon: true,
+                  rightWidget: MyTextView(
+                    userConfig.user?.postsCount ?? "0",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 20,
+                    isFontMedium: true,
+                  ),
+                ).onTap(viewModel.gotoMyPostPage).marginOnly(top: 10),
+
+                //家庭
+                SettingItemContainer(
+                  title: S.current.household,
+                  iconPath: Assets.mainMeHouseholdIcon,
+                  isShowMoreIcon: true,
+                  rightWidget: MyTextView(
+                    userConfig.user?.households?.length.toString() ?? "0",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 20,
+                    isFontMedium: true,
+                  ),
+                ).onTap(viewModel.gotoMyHouseholdPage),
+
+                //房产
+                SettingItemContainer(
+                  title: S.current.estate,
+                  iconPath: Assets.mainMeEstateIcon,
+                  isShowMoreIcon: true,
+                  rightWidget: MyTextView(
+                    userConfig.user?.estates?.fold(0, (sum, estate) {
+                      return sum + (estate.accounts?.length ?? 0);
+                    }).toString() ?? "0",
+                    textColor: context.appColors.textPrimary,
+                    fontSize: 20,
+                    isFontMedium: true,
+                  ),
+                ).onTap(viewModel.gotoMyEstatePage),
+
+                //设置
+                SettingItemContainer(
+                  title: S.current.settings,
+                  iconPath: Assets.mainMeSettingIcon,
+                  isShowMoreIcon: true,
+                ).onTap(viewModel.gotoSettingPage),
+              ],
+            ),
           ),
         ),
       ),

+ 27 - 2
packages/cpt_main/lib/modules/me/me_view_model.dart

@@ -1,13 +1,38 @@
+import 'package:domain/repository/profile_repository.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
-
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/widget_export.dart';
 
 part 'me_view_model.g.dart';
 
 @riverpod
 class MeViewModel extends _$MeViewModel {
+  late final ProfileRepository _profileRepository;
+
   @override
-  void build() {}
+  void build() {
+    _profileRepository = ref.read(profileRepositoryProvider);
+  }
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: false, //允许加载
+  );
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    final result = await _profileRepository.fetchUserInfo();
+    if (result.isSuccess) {
+      UserConfigService.getInstance().setUserInfo(result.data);
+    } else {
+      Log.e(result.errorMsg ?? "UnKnow Error");
+    }
+
+    refreshController.finishRefresh();
+  }
 
   //去我的房产页面
   void gotoMyEstatePage() {

+ 11 - 7
packages/cpt_notice_board/lib/modules/announcement_detail/page/announcement_detail_page.dart

@@ -28,7 +28,6 @@ class AnnouncementDetailPage extends HookConsumerWidget {
     }
   }
 
-
   Widget _buildDetailTop(BuildContext context, WidgetRef ref, _vm) {
     // List itemsList = _vm.state.list.toList();
     return Column(
@@ -116,8 +115,10 @@ class AnnouncementDetailPage extends HookConsumerWidget {
               ),
             ],
           ).marginOnly(top: 15),
-        ]).paddingOnly(bottom: 25).border(bottom: 1,color: ColorUtils.string2Color('#F2F3F6')),
-         Column(
+        ])
+            .paddingOnly(bottom: 25)
+            .border(bottom: 1, color: ColorUtils.string2Color('#F2F3F6')),
+        Column(
           children: [
             const Column(
               mainAxisAlignment: MainAxisAlignment.center,
@@ -157,10 +158,13 @@ class AnnouncementDetailPage extends HookConsumerWidget {
       ),
       body: Container(
           child: EasyRefresh(
-        child: Container(
-            color: ColorUtils.string2Color('#FFFFFF'),
-            padding: const EdgeInsets.only(top: 30, left: 15, right: 15),
-            child: _buildDetailTop(context, ref, _vm)),
+        child: SingleChildScrollView(
+            scrollDirection: Axis.vertical,
+            physics: const BouncingScrollPhysics(),
+            clipBehavior: Clip.none,
+            child: Padding(
+                padding: const EdgeInsets.only(left: 15, right: 15, top: 15),
+                child: _buildDetailTop(context, ref, _vm))),
       )),
     );
   }

+ 25 - 29
packages/cpt_notice_board/lib/modules/event/page/event_page.dart

@@ -28,17 +28,14 @@ class EventPage extends HookConsumerWidget {
   }
 
   Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
-    return Container(
-      // color: Colors.blue,
-      child: Text(
-        maxLines: 2, // 设置最大行数为2
-        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
-        item['title'],
-        style: const TextStyle(
-            fontSize: 16.0,
-            color: Colors.black,
-            fontWeight: FontWeight.w700), // 设置字体大小
-      ),
+    return Text(
+      maxLines: 2, // 设置最大行数为2
+      overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+      item['title'],
+      style: const TextStyle(
+          fontSize: 16.0,
+          color: Colors.black,
+          fontWeight: FontWeight.w700), // 设置字体大小
     );
   }
 
@@ -68,7 +65,7 @@ class EventPage extends HookConsumerWidget {
       ),
       child: Column(
         children: [
-          Container(
+          SizedBox(
             width: MediaQuery.of(context).size.width - 30,
             height: 100,
             // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
@@ -113,23 +110,22 @@ class EventPage extends HookConsumerWidget {
 
     return Scaffold(
       // appBar: AppBar(title: Text("资产")),
-      body: Container(
-          child: EasyRefresh(
-        // 上拉加载
-        onLoad: () async {
-          Log.d("----onLoad");
-          _vm.onLoadData();
-        },
-        // 下拉刷新
-        onRefresh: () async {
-          Log.d("----onRefresh");
-          _vm.refreshListData();
-        },
-        child: Container(
-            color: ColorUtils.string2Color('#F2F3F6'),
-            padding: const EdgeInsets.only(top: 15),
-            child: _buildSaleList(context, ref, _vm)),
-      )),
+      body: EasyRefresh(
+              // 上拉加载
+              onLoad: () async {
+      Log.d("----onLoad");
+      _vm.onLoadData();
+              },
+              // 下拉刷新
+              onRefresh: () async {
+      Log.d("----onRefresh");
+      _vm.refreshListData();
+              },
+              child: Container(
+        color: ColorUtils.string2Color('#F2F3F6'),
+        padding: const EdgeInsets.only(top: 15),
+        child: _buildSaleList(context, ref, _vm)),
+            ),
     );
   }
 }

+ 8 - 5
packages/cpt_notice_board/lib/modules/event_detail/page/event_detail_page.dart

@@ -29,7 +29,7 @@ class EventDetailPage extends HookConsumerWidget {
   }
 
   Widget _buildDetailTop(BuildContext context, WidgetRef ref, _vm) {
-    // List itemsList = _vm.state.list.toList();
+    // List itemsList = _vm.state.list.toList();3
     return Column(
       children: [
         Column(children: [
@@ -111,10 +111,13 @@ class EventDetailPage extends HookConsumerWidget {
       ),
       body: Container(
           child: EasyRefresh(
-        child: Container(
-            color: ColorUtils.string2Color('#FFFFFF'),
-            padding: const EdgeInsets.only(top: 30, left: 15, right: 15),
-            child: _buildDetailTop(context, ref, _vm)),
+        child: SingleChildScrollView(
+            scrollDirection: Axis.vertical,
+            physics: const BouncingScrollPhysics(),
+            clipBehavior: Clip.none,
+            child: Padding(
+                padding: const EdgeInsets.only(left: 15, right: 15, top: 15),
+                child: _buildDetailTop(context, ref, _vm))),
       )),
     );
   }

+ 2 - 5
packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart

@@ -43,9 +43,7 @@ class NoticeBoardPage extends HookConsumerWidget {
           crossAxisAlignment: CrossAxisAlignment.center,
           children: List.generate(topSectionsData.length, (index) {
             final item = topSectionsData[index];
-            return Flexible(
-              flex: 1,
-              child: Column(
+            return Column(
                 children: [
                   Container(
                     width: MediaQuery.of(context).size.width /
@@ -92,8 +90,7 @@ class NoticeBoardPage extends HookConsumerWidget {
                     isFontMedium: true,
                   ),
                 ],
-              ),
-            ).marginOnly(left: 18, right: 18, top: 10, bottom: 10);
+              ).marginOnly(left: 18, right: 18, top: 10, bottom: 10);
           }),
         ),
       ),

+ 69 - 22
packages/cpt_profile/lib/modules/change_mobile/change_mobile_view_model.dart

@@ -1,11 +1,19 @@
 import 'dart:async';
 
 import 'package:cpt_profile/modules/setting/setting_page.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
+import 'package:domain/repository/profile_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
 import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
 import 'package:widgets/widget_export.dart';
@@ -15,34 +23,38 @@ import 'change_mobile_state.dart';
 part 'change_mobile_view_model.g.dart';
 
 @riverpod
-class ChangeMobileViewModel extends _$ChangeMobileViewModel {
+class ChangeMobileViewModel extends _$ChangeMobileViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+  late final AuthRepository _authRepository;
+
   @override
   ChangeMobileState build() {
+    _profileRepository = ref.read(profileRepositoryProvider);
+    _authRepository = ref.read(authRepositoryProvider);
+
     final state = ChangeMobileState();
     initListener(state);
-    ref.onDispose(() {
+
+    registerCancellation(callback: () {
       onDispose(state);
     });
+
     return state;
   }
 
   /// 提交表单修改电话号码
-  void submitChangeMobile() {
+  void submitChangeMobile() async {
     state = state.copyWith(oldCodeErrorText: null, newCodeErrorText: null);
 
-    final FocusNode oldMobileFocusNode = state.formData['old']!['focusNode'];
     final FocusNode newMobileFocusNode = state.formData['new']!['focusNode'];
     final FocusNode newCodeFocusNode = state.formData['new_code']!['focusNode'];
 
-    final TextEditingController oldMobileController = state.formData['old']!['controller'];
     final TextEditingController newMobileController = state.formData['new']!['controller'];
     final TextEditingController newCodeController = state.formData['new_code']!['controller'];
 
-    oldMobileFocusNode.unfocus();
     newMobileFocusNode.unfocus();
     newCodeFocusNode.unfocus();
 
-    final oldMobile = oldMobileController.text;
     final newMobile = newMobileController.text;
     final newCode = newCodeController.text;
 
@@ -59,36 +71,68 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 newMobile:$newMobile newCode:$newCode');
+    final result = await _profileRepository.changeMobilePhone(
+      smsCode: newCode,
+      countryCode: AppConstant.countryCode,
+      phone: newMobile,
+      cancelToken: cancelToken,
+    );
 
-    //返回设置页面
-    SettingPage.startInstance();
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //清除用户登录信息
+      UserConfigService.getInstance().handleLogoutParams();
+      //去登录页面
+      ComponentServiceManager().authService.startAndPopAllLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //展示发送验证码弹窗
-  showVerifyCodedDialog() {
-
-    //展示对应的验证码弹窗
-    _showCAPTCHADialog();
-  }
+  void showVerifyCodedDialog() {
+    final TextEditingController phoneController = state.formData['new']!['controller'];
+    final phone = phoneController.text;
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
 
-  void _showCAPTCHADialog() {
+    //短信验证码之前的图片验证码弹窗
     DialogEngine.show(
-      onDismiss: () {
-      },
+      onDismiss: () {},
       widget: VerifyCodeDialog(
         confirmAction: (key, code) {
-          //发送验证码
-          _startNewCountDown();
+          //发送短信验证码
+          _sendSMS(phone, key, code);
         },
       ),
     );
   }
 
+  /// 调用接口发送短信验证码
+  void _sendSMS(String phone, String? key, String? code) async {
+    final result = await _authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
+
   Timer? newCountdownTimer;
 
   /// 开启倒计时 - New
-  void _startNewCountDown() {
+  void _startCountDown() {
     //60秒倒计时
     state = state.copyWith(isNewCounting: true, newCountdownTime: 60);
 
@@ -108,6 +152,10 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
 
   //初始化监听
   void initListener(ChangeMobileState initState) {
+    final String? phone = UserConfigService.getState().user?.information?.phone;
+    final TextEditingController phoneController = initState.formData['old']!['controller'];
+    phoneController.text = phone ?? "-";
+
     final FocusNode newCodeFocusNode = initState.formData['new_code']!['focusNode'];
 
     newCodeFocusNode.addListener(() {
@@ -127,5 +175,4 @@ class ChangeMobileViewModel extends _$ChangeMobileViewModel {
 
     Log.d("ChangeMobileViewModel 销毁 onDispose");
   }
-
 }

+ 0 - 6
packages/cpt_profile/lib/modules/my_estate/estate_group_data.dart

@@ -1,6 +0,0 @@
-
-//对应分组的数据,需要在ViewModel中处理每一个组的数据
-class EstateGroupData{
-  String? groupId;
-  List<String>? groupDatas=[];
-}

+ 12 - 10
packages/cpt_profile/lib/modules/my_estate/item_estate.dart

@@ -1,6 +1,7 @@
 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:domain/entity/user_me_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
@@ -8,13 +9,15 @@ import 'package:widgets/my_text_view.dart';
 
 class EstateItem extends StatelessWidget {
   final int childIndex; //组内的索引
-  final String item;
+  final UserMeEstatesAccounts item;
   final VoidCallback deleteAction;
+  final VoidCallback itemAction;
 
   const EstateItem({
     required this.childIndex,
     required this.item,
     required this.deleteAction,
+    required this.itemAction,
   });
 
   @override
@@ -31,7 +34,7 @@ class EstateItem extends StatelessWidget {
               Row(
                 children: [
                   MyLoadImage(
-                    "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                    item.avatar,
                     width: 65,
                     height: 65,
                     isCircle: true,
@@ -45,7 +48,7 @@ class EstateItem extends StatelessWidget {
                       const SizedBox(height: 22.5),
                       //姓名
                       MyTextView(
-                        "Wu Bing Bing",
+                        item.name ?? "-",
                         fontSize: 16,
                         isFontBold: true,
                         textColor: context.appColors.textBlack,
@@ -53,14 +56,14 @@ class EstateItem extends StatelessWidget {
                       ),
 
                       MyTextView(
-                        "Owner",
+                        item.type == "1" ? S.current.owner : S.current.tenant,
                         fontSize: 15,
                         isFontRegular: true,
                         textColor: context.appColors.textBlack,
                       ),
 
                       MyTextView(
-                        "Block 35 #08-29",
+                        item.unit?.address ?? "-",
                         fontSize: 15,
                         isFontRegular: true,
                         textColor: context.appColors.textBlack,
@@ -80,23 +83,22 @@ class EstateItem extends StatelessWidget {
                   paddingTop: 16,
                   paddingBottom: 16,
                   fontSize: 16,
+                  onClick: deleteAction,
                   isFontMedium: true,
                   textColor: context.appColors.textPrimary,
                 ),
               )
             ],
           ),
-        ),
-
+        ).onTap(itemAction),
         Visibility(
-          visible: true,
-          child: MyAssetImage(
+          visible: item.isDefault == 1,
+          child: const MyAssetImage(
             Assets.profileMyEstateDefault,
             width: 76,
             height: 44,
           ),
         ).marginOnly(top: childIndex == 0 ? 0 : 10).alignRight(),
-
         MyTextView(
           S.current.approved,
           fontSize: 16,

+ 10 - 7
packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart

@@ -1,6 +1,7 @@
 import 'package:cpt_profile/modules/change_mobile/change_mobile_page.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/user_me_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -24,9 +25,9 @@ class MyEstatePage extends HookConsumerWidget {
   //启动当前页面
   static void startInstance({BuildContext? context}) {
     if (context != null) {
-      context.router.push(const MyEstatePageRoute());
+      context.router.navigate(const MyEstatePageRoute());
     } else {
-      appRouter.push(const MyEstatePageRoute());
+      appRouter.navigate(const MyEstatePageRoute());
     }
   }
 
@@ -56,7 +57,6 @@ class MyEstatePage extends HookConsumerWidget {
           EasyRefresh(
             controller: viewModel.refreshController,
             onRefresh: viewModel.onRefresh,
-            onLoad: viewModel.loadMore,
             child: LoadStateLayout(
               state: state.loadingState,
               errorMessage: state.errorMessage,
@@ -68,9 +68,9 @@ class MyEstatePage extends HookConsumerWidget {
                     delegate: SliverChildBuilderDelegate(
                   (context, index) {
                     return StickyHeader(
-                      header: EstateItemHeader(state.datas[index].groupId),
+                      header: EstateItemHeader(state.datas[index].name),
                       content: Column(
-                        children: _buildGroup(state.datas[index].groupDatas!, index,viewModel),
+                        children: _buildGroup(state.datas[index].accounts!, index,viewModel),
                       ),
                     );
                   },
@@ -98,7 +98,7 @@ class MyEstatePage extends HookConsumerWidget {
   }
 
   //当前组内的子数据
-  List<Widget> _buildGroup(List<String> list, int index, MyEstateViewModel viewModel) {
+  List<Widget> _buildGroup(List<UserMeEstatesAccounts> list, int index, MyEstateViewModel viewModel) {
     return list
         .asMap()
         .map((childIndex, item) {
@@ -107,8 +107,11 @@ class MyEstatePage extends HookConsumerWidget {
               EstateItem(
                 item: item,
                 childIndex: childIndex,
+                itemAction: (){
+                  viewModel.setEstateUnitDefault(item);
+                },
                 deleteAction: () {
-                  viewModel.showRemoveEstateDialog();
+                  viewModel.showRemoveEstateDialog(item.unit?.id);
                 },
               ));
         })

+ 3 - 3
packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart

@@ -1,5 +1,5 @@
+import 'package:domain/entity/user_me_entity.dart';
 import 'package:widgets/load_state_layout.dart';
-import 'estate_group_data.dart';
 
 class MyEstateState{
 
@@ -7,7 +7,7 @@ class MyEstateState{
   LoadState loadingState;
   String? errorMessage;
 
-  List<EstateGroupData> datas; //页面列表数据
+  List<UserMeEstates> datas; //页面列表数据
 
   // ===================================  Begin  ↓  ===================================
 
@@ -21,7 +21,7 @@ class MyEstateState{
     LoadState? loadingState,
     String? errorMessage,
     bool? needShowPlaceholder,
-    List<EstateGroupData>? datas,
+    List<UserMeEstates>? datas,
   }) {
     return MyEstateState(
       errorMessage: errorMessage ?? this.errorMessage,

+ 103 - 97
packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart

@@ -1,8 +1,16 @@
 import 'package:cpt_profile/modules/my_estate/dialog/remove_account_dialog.dart';
-import 'package:cpt_profile/modules/my_estate/estate_group_data.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/user_me_entity.dart';
+import 'package:domain/repository/profile_repository.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
@@ -11,19 +19,27 @@ import 'my_estate_state.dart';
 part 'my_estate_view_model.g.dart';
 
 @riverpod
-class MyEstateViewModel extends _$MyEstateViewModel {
+class MyEstateViewModel extends _$MyEstateViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+
   @override
   MyEstateState build() {
-    return MyEstateState(datas: []);
+    _profileRepository = ref.read(profileRepositoryProvider);
+    final state = MyEstateState(datas: []);
+
+    onInit();
+    registerCancellation(callback: () {
+      unregisterEventBus();
+    });
+    return state;
   }
 
-  var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
     controlFinishRefresh: true, //允许刷新
-    controlFinishLoad: true, //允许加载
+    controlFinishLoad: false, //允许加载
   );
 
   //刷新页面状态
@@ -33,19 +49,11 @@ class MyEstateViewModel extends _$MyEstateViewModel {
 
   // Refresh 刷新事件
   Future onRefresh() async {
-    _curPage = 1;
-    fetchList();
-  }
-
-  // Refresh 加载事件
-  Future loadMore() async {
-    _curPage++;
     fetchList();
   }
 
   // 重试请求
   Future retryRequest() async {
-    _curPage = 1;
     _needShowPlaceholder = true;
     fetchList();
   }
@@ -57,106 +65,104 @@ class MyEstateViewModel extends _$MyEstateViewModel {
     }
 
     // 获取 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));
-
-    List<EstateGroupData> list = [];
-    if (_curPage > 1) {
-
-      //这里只加载一页吧
+    var result = await _profileRepository.fetchUserInfo(
+      cancelToken: cancelToken,
+    );
+
+    // 处理数据
+    if (result.isSuccess) {
+      handleList(result.data?.estates);
     } else {
+      changeLoadingState(LoadState.State_Error, result.errorMsg);
+    }
 
-      list.add(EstateGroupData()
-        ..groupId = "Parc Life"
-        ..groupDatas = ["1", "2",]);
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
 
-      list.add(EstateGroupData()
-        ..groupId = "Little India"
-        ..groupDatas = ["1", "2",]);
+  // 处理数据与展示的逻辑
+  void handleList(List<UserMeEstates>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据
+      state = state.copyWith(datas: list, loadingState: LoadState.State_Success);
+    } else {
+      //展示无数据的布局
+      state = state.copyWith(datas: [], loadingState: LoadState.State_Empty, errorMessage: null);
+    }
 
-      list.add(EstateGroupData()
-        ..groupId = "Marina Bay Sands"
-        ..groupDatas = ["1"]);
+    refreshController.finishRefresh();
+  }
 
+  /// 展示移除账号的提示弹窗
+  void showRemoveEstateDialog(String? unitId) {
+    DialogEngine.show(widget: RemoveAccountDialog(
+      confirmAction: () {
+        _doDeleteEstateUnit(unitId);
+      },
+    ));
+  }
+
+  // 删除指定的单元
+  void _doDeleteEstateUnit(String? unitId) async {
+    final result = await _profileRepository.deleteEstateUnit(unitId: unitId, cancelToken: cancelToken);
+    if (result.isSuccess) {
+      refreshController.callRefresh();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
     }
+  }
 
+  /// 设置默认的房产单元
+  void setEstateUnitDefault(UserMeEstatesAccounts? account) async {
+    if (account == null || account.isDefault == 1) {
+      //已经是默认的不需要操作了
+      return;
+    }
 
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
+    final unitId = account.unit?.id;
 
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
+    final result = await _profileRepository.setUnitAsDefault(unitId: unitId, cancelToken: cancelToken);
 
-      // refreshController.finishLoad();
-      refreshController.finishLoad(IndicatorResult.noMore);
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.successful);
 
-      state = state.copyWith(datas: allList);
+      // 创建一个新的数据列表并更新 isDefault 状态
+      List<UserMeEstates> newDatas = state.datas.map((estate) {
+        var newEstate = estate.copyWith(
+          accounts: estate.accounts?.map((account) {
+            return account.copyWith(
+              isDefault: account.unit?.id == unitId ? 1 : 0,
+            );
+          }).toList(),
+        );
+        return newEstate;
+      }).toList();
+
+      //这里需要传入一个新对象啊,而不是上面的state.datas对象
+      state = state.copyWith(datas: newDatas);
+
+      //刷新用户的信息
+      UserConfigService.getInstance().refreshUserInfo();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
     }
+  }
 
-    // 最后赋值
-    _needShowPlaceholder = false;
+  //初始化
+  void onInit() {
+    registerEventBus();
   }
 
-// 处理数据与展示的逻辑
-// 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);
-//     }
-//   }
-// }
+  Subscription? subscribe;
 
-  /// 展示移除账号的提示弹窗
-  void showRemoveEstateDialog() {
-    DialogEngine.show(widget: RemoveAccountDialog(
-      confirmAction: () {
-        ToastEngine.show("确定去删除");
-      },
-    ));
+  void registerEventBus() {
+    subscribe = bus.on(AppConstant.eventEstateRefresh, (arg) {
+      Log.d("收到信息-需要刷新My Estate的列表");
+      refreshController.callRefresh();
+    });
   }
 
+  void unregisterEventBus() {
+    bus.off(AppConstant.eventEstateRefresh, subscribe);
+  }
 }

+ 10 - 10
packages/cpt_profile/lib/modules/my_household/item_household.dart

@@ -1,5 +1,6 @@
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/user_me_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
@@ -7,7 +8,7 @@ import 'package:widgets/my_text_view.dart';
 
 class HouseholdItem extends StatelessWidget {
   final int index;
-  final String item;
+  final UserMeHouseholds item;
 
   const HouseholdItem({
     required this.index,
@@ -25,19 +26,18 @@ class HouseholdItem extends StatelessWidget {
         mainAxisSize: MainAxisSize.max,
         children: [
           MyLoadImage(
-            "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+            item.avatar,
             width: 65,
             height: 65,
             isCircle: true,
           ).marginOnly(right: 17),
-
-        MyTextView(
-          "Wu Bing Bing",
-          fontSize: 17,
-          isFontBold: true,
-          textColor: context.appColors.textBlack,
-          maxLines: 2,
-        ).expanded(),
+          MyTextView(
+            item.name ?? "-",
+            fontSize: 17,
+            isFontBold: true,
+            textColor: context.appColors.textBlack,
+            maxLines: 2,
+          ).expanded(),
         ],
       ),
     );

+ 3 - 3
packages/cpt_profile/lib/modules/my_household/my_household_page.dart

@@ -4,8 +4,8 @@ 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:plugin_basic/provider/user_config/user_config_service.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_text_view.dart';
@@ -53,7 +53,6 @@ class MyHouseholdPage extends HookConsumerWidget {
         child: EasyRefresh(
           controller: viewModel.refreshController,
           onRefresh: viewModel.onRefresh,
-          onLoad: viewModel.loadMore,
           child: LoadStateLayout(
             state: state.loadingState,
             errorMessage: state.errorMessage,
@@ -81,9 +80,10 @@ class MyHouseholdPage extends HookConsumerWidget {
 
   //顶部的房产布局
   Widget _buildEstateWidget(BuildContext context) {
+    ;
     return SliverToBoxAdapter(
       child: MyTextView(
-        "Owner 35 #08-29",
+        UserConfigService.getState().user?.defaultUnit?.address ?? "",
         fontSize: 20,
         paddingLeft: 15,
         paddingRight: 15,

+ 3 - 2
packages/cpt_profile/lib/modules/my_household/my_household_state.dart

@@ -1,3 +1,4 @@
+import 'package:domain/entity/user_me_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class MyHouseholdState{
@@ -6,7 +7,7 @@ class MyHouseholdState{
   LoadState loadingState;
   String? errorMessage;
 
-  List<String> datas; //页面列表数据
+  List<UserMeHouseholds> datas; //页面列表数据
 
   // ===================================  Begin  ↓  ===================================
 
@@ -20,7 +21,7 @@ class MyHouseholdState{
     LoadState? loadingState,
     String? errorMessage,
     bool? needShowPlaceholder,
-    List<String>? datas,
+    List<UserMeHouseholds>? datas,
   }) {
     return MyHouseholdState(
       errorMessage: errorMessage ?? this.errorMessage,

+ 30 - 78
packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart

@@ -1,3 +1,6 @@
+import 'package:domain/entity/user_me_entity.dart';
+import 'package:domain/repository/profile_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
@@ -7,19 +10,23 @@ import 'my_household_state.dart';
 part 'my_household_view_model.g.dart';
 
 @riverpod
-class MyHouseholdViewModel extends _$MyHouseholdViewModel {
+class MyHouseholdViewModel extends _$MyHouseholdViewModel with DioCancelableMixin {
+  late final ProfileRepository _profileRepository;
+
   @override
   MyHouseholdState build() {
-    return MyHouseholdState(datas: []);
+    _profileRepository = ref.read(profileRepositoryProvider);
+    final state = MyHouseholdState(datas: []);
+    registerCancellation();
+    return state;
   }
 
-  var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: false, //允许加载
   );
 
   //刷新页面状态
@@ -29,19 +36,11 @@ class MyHouseholdViewModel extends _$MyHouseholdViewModel {
 
   // Refresh 刷新事件
   Future onRefresh() async {
-    _curPage = 1;
-    fetchList();
-  }
-
-  // Refresh 加载事件
-  Future loadMore() async {
-    _curPage++;
     fetchList();
   }
 
   // 重试请求
   Future retryRequest() async {
-    _curPage = 1;
     _needShowPlaceholder = true;
     fetchList();
   }
@@ -53,78 +52,31 @@ class MyHouseholdViewModel extends _$MyHouseholdViewModel {
     }
 
     // 获取 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"];
+    var result = await _profileRepository.fetchUserInfo(
+      cancelToken: cancelToken,
+    );
 
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
+    // 处理数据
+    if (result.isSuccess) {
+      handleList(result.data?.households);
     } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
-
-      state = state.copyWith(datas: allList);
+      changeLoadingState(LoadState.State_Error, result.errorMsg);
     }
 
     // 最后赋值
     _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 handleList(List<UserMeHouseholds>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据
+      state = state.copyWith(datas: list, loadingState: LoadState.State_Success);
+    } else {
+      //展示无数据的布局
+      state = state.copyWith(datas: [], loadingState: LoadState.State_Empty, errorMessage: null);
+    }
 
+    refreshController.finishRefresh();
+  }
 }

+ 11 - 3
packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart

@@ -6,6 +6,7 @@ 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';
@@ -34,6 +35,13 @@ class ProfileEditPage extends HookConsumerWidget {
     final viewModel = ref.watch(profileEditViewModelProvider.notifier);
     final state = ref.watch(profileEditViewModelProvider);
 
+    useEffect(() {
+      // 执行接口请求
+      Future.microtask(() => viewModel.fetchDefaultAvatar());
+      return () {
+      };
+    }, []);
+
     return Scaffold(
       appBar: MyAppBar.appBar(context, S.current.edit_profile,backgroundColor: context.appColors.backgroundWhite),
       backgroundColor: context.appColors.backgroundDefault,
@@ -56,7 +64,7 @@ class ProfileEditPage extends HookConsumerWidget {
                     children: [
                       //默认的占位图
                       Visibility(
-                        visible: true,
+                        visible: state.avatarPath == null,
                         child: const Align(
                           alignment: Alignment.bottomCenter,
                           child: MyAssetImage(
@@ -69,9 +77,9 @@ class ProfileEditPage extends HookConsumerWidget {
 
                       //用户的头像
                       Visibility(
-                        visible: false,
+                        visible: state.avatarPath != null,
                         child: MyLoadImage(
-                          "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                          state.avatarPath,
                           width: 80,
                           height: 80,
                           isCircle: true,

+ 10 - 17
packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart

@@ -2,34 +2,27 @@ 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:hooks_riverpod/hooks_riverpod.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 
-class AvatarEditDialog extends StatelessWidget {
+import '../profile_edit_view_model.dart';
+
+class AvatarEditDialog extends HookConsumerWidget {
   void Function(String path) otherAction;
   void Function() photoAction;
 
-  final List<String> otherImages = [
-    "https://pic.rmb.bdstatic.com/bjh/bc3fcc5fadee3ab70dc6f941ae3eb4a21534.jpeg@h_1280",
-    "https://img0.baidu.com/it/u=3885044482,1194334042&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
-    "https://q0.itc.cn/q_70/images03/20240508/64f00aea4daa4b808e59fdadb939ff41.jpeg",
-    "https://ww3.sinaimg.cn/mw690/d315af46ly1h7wfnspdomj20u00u0tef.jpg",
-    "https://ww2.sinaimg.cn/mw690/006A8Z5cly1hrhndmtmuaj30he0htq55.jpg",
-    "https://ww1.sinaimg.cn/mw690/d315af46ly1h7wfnuxn91j20j60j60uk.jpg",
-    "https://img0.baidu.com/it/u=80291486,3068765574&fm=253&fmt=auto&app=138&f=JPEG?w=380&h=380",
-    "https://img0.baidu.com/it/u=528233043,1559727912&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500",
-    "https://img0.baidu.com/it/u=691481429,1364097496&fm=253&fmt=auto?w=500&h=500"
-  ];
-
   AvatarEditDialog({
     required this.photoAction,
     required this.otherAction,
   });
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context,WidgetRef ref) {
+    final state = ref.watch(profileEditViewModelProvider);
+
     return Column(
       crossAxisAlignment: CrossAxisAlignment.center,
       mainAxisAlignment: MainAxisAlignment.center,
@@ -101,12 +94,12 @@ class AvatarEditDialog extends StatelessWidget {
                   crossAxisSpacing: 15.0, // 交叉轴(左右)的间距
                   childAspectRatio: 1, // 宽高比例
                 ),
-                itemCount: otherImages.length,
+                itemCount: state.defaultAvatars?.length ?? 0,
                 itemBuilder: (context, index) {
                   return Center(
-                    child: MyLoadImage(otherImages[index]).onTap((){
+                    child: MyLoadImage(state.defaultAvatars?[index]).onTap((){
                       onCancel();
-                      otherAction.call(otherImages[index]);
+                      otherAction.call(state.defaultAvatars?[index]??"");
                     }),
                   );
                 },

+ 4 - 0
packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart

@@ -5,6 +5,7 @@ class ProfileEditState{
   //表单的校验与数据
   final Map<String, Map<String, dynamic>> formData;
 
+  List<String>? defaultAvatars;  //默认头像
   String? avatarPath;  //头像的路径或Uri
 
   // ===================================  Begin  ↓  ===================================
@@ -12,6 +13,7 @@ class ProfileEditState{
   ProfileEditState({
     Map<String, Map<String, dynamic>>? formData,
     this.avatarPath,
+    this.defaultAvatars,
   }) : formData = formData ??
       {
         'first_name': {
@@ -39,10 +41,12 @@ class ProfileEditState{
 
   ProfileEditState copyWith({
     String? avatarPath,
+    List<String>? defaultAvatars,
   }) {
     return ProfileEditState(
       formData: this.formData,
       avatarPath: avatarPath ?? this.avatarPath,
+      defaultAvatars: defaultAvatars ?? this.defaultAvatars,
     );
   }
 

+ 87 - 7
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart

@@ -1,24 +1,48 @@
 import 'package:cpt_profile/modules/profile_edit/dialog/avatar_edit_dialog.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/profile_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'profile_edit_state.dart';
 import 'package:plugin_platform/platform_export.dart';
 
 part 'profile_edit_view_model.g.dart';
 
 @riverpod
-class ProfileEditViewModel extends _$ProfileEditViewModel {
+class ProfileEditViewModel extends _$ProfileEditViewModel with DioCancelableMixin {
+  late final ProfileRepository profileRepository;
+
   @override
   ProfileEditState build() {
-    return ProfileEditState();
+    profileRepository = ref.read(profileRepositoryProvider);
+
+    final state = initState();
+
+    registerCancellation();
+
+    return state;
+  }
+
+  // 获取默认的头像
+  void fetchDefaultAvatar() async {
+    final result = await profileRepository.fetchDefaultAvatar(cancelToken: cancelToken);
+    if (result.isSuccess) {
+      state = state.copyWith(defaultAvatars: result.list);
+    } else {
+      Log.e(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   /// 提交编辑用户信息
-  void submitEdit() {
+  void submitEdit() async {
     final FocusNode firstNameFocusNode = state.formData['first_name']!['focusNode'];
     final FocusNode lastNameFocusNode = state.formData['last_name']!['focusNode'];
     final FocusNode emailFocusNode = state.formData['email']!['focusNode'];
@@ -37,10 +61,45 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
 
     Log.d('当前待提交的 firstName:$firstName lastName:$lastName email:$email');
 
+    if (Utils.isEmpty(firstName)) {
+      ToastEngine.show('First Name cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(lastName)) {
+      ToastEngine.show('Last Name cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(email)) {
+      ToastEngine.show('Email cannot be empty!');
+      return;
+    }
+
+    if (Utils.isEmpty(state.avatarPath)) {
+      ToastEngine.show('Please select an avatar as your profile picture');
+      return;
+    }
+
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 firstName:$firstName lastName:$lastName email:$email ');
+    final result = await profileRepository.updateProfile(
+      firstName: firstName,
+      lastName: lastName,
+      email: email,
+      avatarPath: state.avatarPath,
+      cancelToken: cancelToken,
+    );
 
-    appRouter.maybePop();
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //刷新用户信息
+      UserConfigService.getInstance().refreshUserInfo();
+      //返回
+      appRouter.maybePop();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //去编辑头像页面
@@ -48,7 +107,7 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
     DialogEngine.show(
         widget: AvatarEditDialog(
       otherAction: (path) {
-        ToastEngine.show("点击了图片:$path");
+        state = state.copyWith(avatarPath: path);
       },
       photoAction: () {
         //选择相机相册
@@ -60,7 +119,28 @@ class ProfileEditViewModel extends _$ProfileEditViewModel {
   //相机相册选择
   void _pickPhoto(BuildContext context) {
     ImagePickerUtils().show(context, (path) {
-      ToastEngine.show("选中了图片:$path");
+      state = state.copyWith(avatarPath: path);
     });
   }
+
+  // 初始化
+  ProfileEditState initState() {
+    final String? avatarPath = UserConfigService.getState().user?.avatar;
+    final initState = ProfileEditState(avatarPath: Utils.isEmpty(avatarPath) ? null : avatarPath);
+
+    final String? firstName = UserConfigService.getState().user?.information?.firstName;
+    final String? lastName = UserConfigService.getState().user?.information?.lastName;
+    final String? email = UserConfigService.getState().user?.email;
+
+    final TextEditingController firstNameController = initState.formData['first_name']!['controller'];
+    firstNameController.text = firstName ?? "";
+
+    final TextEditingController lastNameController = initState.formData['last_name']!['controller'];
+    lastNameController.text = lastName ?? "";
+
+    final TextEditingController emailController = initState.formData['email']!['controller'];
+    emailController.text = email ?? "";
+
+    return initState;
+  }
 }

+ 3 - 0
packages/cpt_profile/lib/modules/reset_password/reset_password_page.dart

@@ -82,6 +82,7 @@ class ResetPasswordPage extends HookConsumerWidget {
                     context,
                     state,
                     "phone",
+                    enable: false,
                     textInputType: TextInputType.number,
                     textInputAction: TextInputAction.next,
                     onSubmit: (formKey, value) {
@@ -241,6 +242,7 @@ class ResetPasswordPage extends HookConsumerWidget {
         TextInputType textInputType = TextInputType.text,
         String? errorText,
         bool obscureText = false,
+        bool enable = true,
         TextInputAction textInputAction = TextInputAction.done,
         Function? onSubmit,
       }) {
@@ -260,6 +262,7 @@ class ResetPasswordPage extends HookConsumerWidget {
         margin: EdgeInsets.only(top: marginTop),
         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
         showDivider: false,
+        enabled: enable,
         height: 44,
         style: TextStyle(
           color: context.appColors.authFiledText,

+ 64 - 7
packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.dart

@@ -1,9 +1,17 @@
 import 'dart:async';
 
 import 'package:cpt_profile/modules/reset_password/reset_password_state.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/auth_repository.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/dialog/verify_code_dialog.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
@@ -12,8 +20,12 @@ part 'reset_password_view_model.g.dart';
 
 @riverpod
 class ResetPasswordViewModel extends _$ResetPasswordViewModel {
+  late final AuthRepository authRepository;
+
   @override
   ResetPasswordState build() {
+    authRepository = ref.read(authRepositoryProvider);
+
     final state = ResetPasswordState();
     initListener(state);
     ref.onDispose(() {
@@ -23,7 +35,7 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
   }
 
   /// 提交重置密码请求
-  void submitResetPassword() {
+  void submitResetPassword() async {
     state = state.copyWith(codeErrorText: null, passwordErrorText: null, confirmPasswordErrorText: null);
 
     final FocusNode phoneFocusNode = state.formData['phone']!['focusNode'];
@@ -49,7 +61,7 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
     Log.d('当前待提交的 phone:$phone code:$code password:$password confirmPassword:$confirmPassword');
 
     if (Utils.isEmpty(phone)) {
-      ToastEngine.show("Enter Mobile Phone");
+      ToastEngine.show("Mobile Phone Error");
       return;
     }
 
@@ -74,10 +86,18 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 phone:$phone code:$code password:$password confirmPassword:$confirmPassword');
-
-    //页面返回
-    appRouter.maybePop();
+    final result = await authRepository.resetPassword(smsCode: code, password: password, confirmPassword: confirmPassword);
+
+    if (result.isSuccess) {
+      //提示成功
+      NotifyEngine.showSuccess(S.current.successful);
+      //清除用户登录信息
+      UserConfigService.getInstance().handleLogoutParams();
+      //去登录页面
+      ComponentServiceManager().authService.startAndPopAllLoginPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //切换隐藏显示密码
@@ -90,7 +110,40 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
   }
 
   void showVerifyCodedDialog() {
-    _startCountDown();
+    final TextEditingController phoneController = state.formData['phone']!['controller'];
+    final phone = phoneController.text;
+    if (Utils.isEmpty(phone)) {
+      ToastEngine.show("Mobile Phone Error");
+      return;
+    }
+
+    //短信验证码之前的图片验证码弹窗
+    DialogEngine.show(
+      onDismiss: () {},
+      widget: VerifyCodeDialog(
+        confirmAction: (key, code) {
+          //发送短信验证码
+          _sendSMS(phone, key, code);
+        },
+      ),
+    );
+  }
+
+  /// 调用接口发送短信验证码
+  void _sendSMS(String phone, String? key, String? code) async {
+    final result = await authRepository.sendSMS(
+      countryCode: AppConstant.countryCode,
+      phone: phone,
+      captchaKey: key,
+      captchaValue: code,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.send_sms_successful);
+      _startCountDown();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   Timer? countdownTimer;
@@ -116,6 +169,10 @@ class ResetPasswordViewModel extends _$ResetPasswordViewModel {
 
   //初始化监听
   void initListener(ResetPasswordState initState) {
+    final String? phone = UserConfigService.getState().user?.information?.phone;
+    final TextEditingController phoneController = initState.formData['phone']!['controller'];
+    phoneController.text = phone ?? "-";
+
     final FocusNode codeFocusNode = initState.formData['code']!['focusNode'];
     final FocusNode passwordFocusNode = initState.formData['password']!['focusNode'];
     final FocusNode confirmPasswordFocusNode = initState.formData['confirm_password']!['focusNode'];

+ 0 - 33
packages/cpt_rewards/lib/modules/rewards/page/rewards_page.dart

@@ -1,33 +0,0 @@
-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 '../../../router/page/rewards_page_router.dart';
-import '../../rewards/vm/rewards_view_model.dart';
-
-@RoutePage()
-class RewardsPage extends HookConsumerWidget {
-  const RewardsPage({Key? key}) : super(key: key);
-
-  //启动当前页面
-  static void startInstance({BuildContext? context}) {
-    if (context != null) {
-      context.router.push(const RewardsPageRoute());
-    } else {
-      appRouter.push(const RewardsPageRoute());
-    }
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.read(rewardsViewModelProvider.notifier);
-
-    return Scaffold(
-      appBar: AppBar(title: Text("奖励")),
-      body: Center(
-        child: Text("奖励的主页面"),
-      ),
-    );
-  }
-}

+ 918 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_page.dart

@@ -0,0 +1,918 @@
+import 'package:cpt_rewards/modules/rewards_address/rewards_address_page.dart';
+import 'package:cpt_rewards/modules/rewards_code/rewards_code_page.dart';
+import 'package:cpt_rewards/modules/rewards_history/rewards_history_page.dart';
+import 'package:cpt_rewards/modules/rewards_home/rewards_home_page.dart';
+import 'package:cpt_rewards/modules/rewards_list/rewards_list_page.dart';
+import 'package:cpt_rewards/modules/rewards_my/rewards_my_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/image/image_nine_grid.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_vm.dart';
+
+@RoutePage()
+class RewardsPage extends HookConsumerWidget {
+  const RewardsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsPageRoute());
+    } else {
+      appRouter.push(const RewardsPageRoute());
+    }
+  }
+
+  Widget _buildTop(BuildContext context, WidgetRef ref, _vm) {
+    // List itemsList = _vm.state.list.toList();
+    return Container(
+        decoration: BoxDecoration(
+          border: Border(
+              bottom: BorderSide(
+            color: ColorUtils.string2Color('#4161D0'), // 设置bottom边框的颜色
+            width: 45.0, // 设置bottom边框的宽度
+          )),
+          borderRadius: const BorderRadius.only(
+            topLeft: Radius.circular(0.0),
+            topRight: Radius.circular(0.0),
+            bottomLeft: Radius.circular(30.0),
+            bottomRight: Radius.circular(30.0),
+          ), // 圆角
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const MyAssetImage(
+              Assets.rewardsRewardsBack,
+              width: 44,
+              height: 44,
+            ),
+            // const Text(
+            //   '1526 Available Points',
+            //   style: TextStyle(
+            //       fontSize: 18.0,
+            //       color: Colors.white,
+            //       fontWeight: FontWeight.w500), // 设置字体大小
+            // ).paddingOnly(left: 10, top: 20, bottom: 18),
+            Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                const Text(
+                  'Available Points',
+                  style: TextStyle(
+                      fontSize: 17.0,
+                      color: Colors.white,
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ),
+                Container(
+                  decoration: BoxDecoration(
+                    border: Border.all(color: Colors.white, width: 1), // 边框
+                    borderRadius: BorderRadius.circular(8), // 圆角
+                  ),
+                  child: Row(
+                    children: [
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ).marginOnly(right: 5),
+                      const Text(
+                        '1022',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: Colors.white,
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                    ],
+                  ).paddingOnly(left: 10, top: 7, bottom: 7, right: 10),
+                ),
+              ],
+            ).paddingOnly(left: 10, top: 20, bottom: 18),
+          ],
+        )
+            .paddingOnly(top: 15, left: 5, right: 15, bottom: 0)
+            .border(bottom: 0, color: ColorUtils.string2Color('#4161D0'))
+            .backgroundColor(ColorUtils.string2Color('#4161D0')));
+  }
+
+  Widget _buildSearch(BuildContext context, WidgetRef ref, _vm) {
+    // List itemsList = _vm.state.list.toList();
+    return Container(
+      width: MediaQuery.of(context).size.width - 30,
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(10),
+        boxShadow: const [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          Text(
+            'Continuous Login 8 Day',
+            style: TextStyle(
+                fontSize: 15.0,
+                color: ColorUtils.string2Color('#000000'),
+                fontWeight: FontWeight.w500), // 设置字体大小
+          ),
+          Flex(
+            direction: Axis.horizontal,
+            children: [
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#4161D0'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        '11/01',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#4161D0'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#4161D0'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 15.0),
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#4161D0'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#4161D0'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        'Today',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#ffffff'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#ffffff'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 15.0),
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#F2F3F6'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        'Today',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 15.0),
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#F2F3F6'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        'Today',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+            ],
+          ).marginOnly(top: 13, bottom: 13),
+          Flex(
+            direction: Axis.horizontal,
+            children: [
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#F2F3F6'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        'Today',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 15.0),
+              Expanded(
+                flex: 1,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#F2F3F6'), width: 1),
+                  ),
+                  height: 78,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Text(
+                        'Today',
+                        style: TextStyle(
+                            fontSize: 13.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w400), // 设置字体大小
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconJb,
+                        width: 23,
+                        height: 23,
+                      ),
+                      Text(
+                        '+2',
+                        style: TextStyle(
+                            fontSize: 15.0,
+                            color: ColorUtils.string2Color('#000000'),
+                            fontWeight: FontWeight.w500), // 设置字体大小
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 15.0),
+              Expanded(
+                flex: 2,
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    borderRadius: BorderRadius.circular(10),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#F2F3F6'), width: 1),
+                  ),
+                  height: 78,
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Column(
+                        crossAxisAlignment: CrossAxisAlignment.center,
+                        // mainAxisAlignment: MainAxisAlignment.center,
+                        children: [
+                          Text(
+                            'Today',
+                            style: TextStyle(
+                                fontSize: 13.0,
+                                color: ColorUtils.string2Color('#000000'),
+                                fontWeight: FontWeight.w400), // 设置字体大小
+                          ),
+                          Text(
+                            '+ More',
+                            style: TextStyle(
+                                fontSize: 12.0,
+                                color: ColorUtils.string2Color('#000000'),
+                                fontWeight: FontWeight.w500), // 设置字体大小
+                          ),
+                        ],
+                      ),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsIconYdjb,
+                        width: 67,
+                        height: 57,
+                      ).paddingOnly(top: 7),
+                    ],
+                  ).paddingOnly(top: 8, left: 13, right: 4),
+                ),
+              ),
+            ],
+          ),
+        ],
+      ).paddingOnly(left: 15, right: 15, top: 15, bottom: 15),
+    );
+  }
+
+  Widget _buildSwiper(BuildContext context, WidgetRef ref, _vm) {
+    return Container(
+      // color: Colors.white,
+      height: 55,
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(10),
+        boxShadow: const [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          Text(
+            'How To Get Rewards?',
+            style: TextStyle(
+                fontSize: 15.0,
+                color: ColorUtils.string2Color('#000000'),
+                fontWeight: FontWeight.w500), // 设置字体大小
+          ),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 10, bottom: 10, left: 17, right: 17),
+            decoration: BoxDecoration(
+              color: ColorUtils.string2Color('#4161D0'),
+              borderRadius: BorderRadius.circular(5),
+            ),
+            child: Text(
+              'Rewards',
+              style: TextStyle(
+                  fontSize: 14.0,
+                  color: ColorUtils.string2Color('#ffffff'),
+                  fontWeight: FontWeight.w400), // 设置字体大小
+            ).onTap(() {
+              RewardsHomePage.startInstance();
+            }),
+          ),
+        ],
+      ).paddingOnly(left: 15, right: 15),
+    ).marginOnly(top: 12, bottom: 12);
+  }
+
+  Widget _buildList(BuildContext context, WidgetRef ref, _vm) {
+    return Container(
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(10),
+        boxShadow: const [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Row(
+                  children: [
+                    Container(
+                      padding: const EdgeInsets.only(
+                          top: 10, bottom: 10, left: 17, right: 17),
+                      decoration: BoxDecoration(
+                        color: ColorUtils.string2Color('#f2f3f6'),
+                        borderRadius: BorderRadius.circular(5),
+                      ),
+                      child: const MyAssetImage(
+                        Assets.rewardsRewardsIconIm,
+                        width: 29,
+                        height: 24,
+                      ),
+                    ).marginOnly(right: 12),
+                    Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Text(
+                          'Daily Login',
+                          style: TextStyle(
+                              fontSize: 15.0,
+                              color: ColorUtils.string2Color('#000000'),
+                              fontWeight: FontWeight.w500), // 设置字体大小
+                        ).marginOnly(bottom: 6),
+                        Row(
+                          children: [
+                            Text(
+                              '+2',
+                              style: TextStyle(
+                                  fontSize: 15.0,
+                                  color: ColorUtils.string2Color('#4161D0'),
+                                  fontWeight: FontWeight.w500), // 设置字体大小
+                            ),
+                            const MyAssetImage(
+                              Assets.rewardsRewardsIconJb,
+                              width: 14,
+                              height: 14,
+                            )
+                          ],
+                        )
+                      ],
+                    )
+                  ],
+                ),
+                Container(
+                  width: 86,
+                  height: 30,
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#ffffff'),
+                    borderRadius: BorderRadius.circular(5),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#4161D0'), width: 1),
+                  ),
+                  child: Center(
+                    child: Text(
+                      'Check In',
+                      style: TextStyle(
+                          fontSize: 14.0,
+                          color: ColorUtils.string2Color('#4161D0'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Row(
+                  children: [
+                    Container(
+                      padding: const EdgeInsets.only(
+                          top: 10, bottom: 10, left: 17, right: 17),
+                      decoration: BoxDecoration(
+                        color: ColorUtils.string2Color('#f2f3f6'),
+                        borderRadius: BorderRadius.circular(5),
+                      ),
+                      child: const MyAssetImage(
+                        Assets.rewardsRewardsIconIm,
+                        width: 29,
+                        height: 24,
+                      ),
+                    ).marginOnly(right: 12),
+                    Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Text(
+                          'Daily Login',
+                          style: TextStyle(
+                              fontSize: 15.0,
+                              color: ColorUtils.string2Color('#000000'),
+                              fontWeight: FontWeight.w500), // 设置字体大小
+                        ).marginOnly(bottom: 6),
+                        Row(
+                          children: [
+                            Text(
+                              '+2',
+                              style: TextStyle(
+                                  fontSize: 15.0,
+                                  color: ColorUtils.string2Color('#4161D0'),
+                                  fontWeight: FontWeight.w500), // 设置字体大小
+                            ),
+                            const MyAssetImage(
+                              Assets.rewardsRewardsIconJb,
+                              width: 14,
+                              height: 14,
+                            )
+                          ],
+                        )
+                      ],
+                    )
+                  ],
+                ),
+                Container(
+                  width: 86,
+                  height: 30,
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#ffffff'),
+                    borderRadius: BorderRadius.circular(5),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#4161D0'), width: 1),
+                  ),
+                  child: Center(
+                    child: Text(
+                      'Check In',
+                      style: TextStyle(
+                          fontSize: 14.0,
+                          color: ColorUtils.string2Color('#4161D0'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Row(
+                  children: [
+                    Container(
+                      padding: const EdgeInsets.only(
+                          top: 10, bottom: 10, left: 17, right: 17),
+                      decoration: BoxDecoration(
+                        color: ColorUtils.string2Color('#f2f3f6'),
+                        borderRadius: BorderRadius.circular(5),
+                      ),
+                      child: const MyAssetImage(
+                        Assets.rewardsRewardsIconIm,
+                        width: 29,
+                        height: 24,
+                      ),
+                    ).marginOnly(right: 12),
+                    Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Text(
+                          'Daily Login',
+                          style: TextStyle(
+                              fontSize: 15.0,
+                              color: ColorUtils.string2Color('#000000'),
+                              fontWeight: FontWeight.w500), // 设置字体大小
+                        ).marginOnly(bottom: 6),
+                        Row(
+                          children: [
+                            Text(
+                              '+2',
+                              style: TextStyle(
+                                  fontSize: 15.0,
+                                  color: ColorUtils.string2Color('#4161D0'),
+                                  fontWeight: FontWeight.w500), // 设置字体大小
+                            ),
+                            const MyAssetImage(
+                              Assets.rewardsRewardsIconJb,
+                              width: 14,
+                              height: 14,
+                            )
+                          ],
+                        )
+                      ],
+                    )
+                  ],
+                ),
+                Container(
+                  width: 86,
+                  height: 30,
+                  decoration: BoxDecoration(
+                    color: ColorUtils.string2Color('#ffffff'),
+                    borderRadius: BorderRadius.circular(5),
+                    border: Border.all(
+                        color: ColorUtils.string2Color('#4161D0'), width: 1),
+                  ),
+                  child: Center(
+                    child: Text(
+                      'Check In',
+                      style: TextStyle(
+                          fontSize: 14.0,
+                          color: ColorUtils.string2Color('#4161D0'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          )
+        ],
+      ),
+    ).marginOnly(bottom: 12);
+  }
+
+  Widget _buildHistory(BuildContext context, WidgetRef ref, _vm) {
+    return Container(
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(10),
+        boxShadow: const [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Text(
+                  'Points History',
+                  style: TextStyle(
+                      fontSize: 15.0,
+                      color: ColorUtils.string2Color('#000000'),
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ),
+                Text(
+                  'More >',
+                  style: TextStyle(
+                      fontSize: 15.0,
+                      color: ColorUtils.string2Color('#4161D0'),
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ).onTap(() {
+                  RewardsHistoryPage.startInstance();
+                })
+              ]).paddingOnly(left: 15, right: 15, top: 15, bottom: 5),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    Text(
+                      'Daily Login',
+                      style: TextStyle(
+                          fontSize: 15.0,
+                          color: ColorUtils.string2Color('#000000'),
+                          fontWeight: FontWeight.w500), // 设置字体大小
+                    ).marginOnly(bottom: 6),
+                    Text(
+                      '14 Oct 2024  10:00PM',
+                      style: TextStyle(
+                          fontSize: 13.0,
+                          color: ColorUtils.string2Color('#808DAF'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ],
+                ),
+                Text(
+                  '+2',
+                  style: TextStyle(
+                      fontSize: 20.0,
+                      color: ColorUtils.string2Color('#FDB429'),
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ),
+              ],
+            ),
+          ),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    Text(
+                      'Daily Login',
+                      style: TextStyle(
+                          fontSize: 15.0,
+                          color: ColorUtils.string2Color('#000000'),
+                          fontWeight: FontWeight.w500), // 设置字体大小
+                    ).marginOnly(bottom: 6),
+                    Text(
+                      '14 Oct 2024  10:00PM',
+                      style: TextStyle(
+                          fontSize: 13.0,
+                          color: ColorUtils.string2Color('#808DAF'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ],
+                ),
+                Text(
+                  '+2',
+                  style: TextStyle(
+                      fontSize: 20.0,
+                      color: ColorUtils.string2Color('#FDB429'),
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ),
+              ],
+            ),
+          ),
+          Container(
+            padding:
+                const EdgeInsets.only(top: 15, bottom: 15, left: 15, right: 15),
+            decoration: BoxDecoration(
+                border: Border(
+                    bottom: BorderSide(
+              width: 1.0, // 底边边框的宽度
+              color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+            ))),
+            child: Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    Text(
+                      'Daily Login',
+                      style: TextStyle(
+                          fontSize: 15.0,
+                          color: ColorUtils.string2Color('#000000'),
+                          fontWeight: FontWeight.w500), // 设置字体大小
+                    ).marginOnly(bottom: 6),
+                    Text(
+                      '14 Oct 2024  10:00PM',
+                      style: TextStyle(
+                          fontSize: 13.0,
+                          color: ColorUtils.string2Color('#808DAF'),
+                          fontWeight: FontWeight.w400), // 设置字体大小
+                    ),
+                  ],
+                ),
+                Text(
+                  '+2',
+                  style: TextStyle(
+                      fontSize: 20.0,
+                      color: ColorUtils.string2Color('#FDB429'),
+                      fontWeight: FontWeight.w500), // 设置字体大小
+                ),
+              ],
+            ),
+          ),
+        ],
+      ),
+    ).marginOnly(bottom: 12);
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("奖励")),
+      body: Column(children: [
+        Expanded(
+          child: SingleChildScrollView(
+              scrollDirection: Axis.vertical,
+              physics: const BouncingScrollPhysics(),
+              clipBehavior: Clip.none,
+              child: Column(
+                children: [
+                  _buildTop(context, ref, _vm),
+                  Container(
+                    transform: Matrix4.translationValues(0.0, -45.0, 0.0),
+                    child: Column(
+                      children: [
+                        _buildSearch(context, ref, _vm),
+                        _buildSwiper(context, ref, _vm),
+                        _buildList(context, ref, _vm),
+                        _buildHistory(context, ref, _vm),
+                      ],
+                    ), // 使用负数margin
+                  ).paddingOnly(left: 15, right: 15),
+                ],
+              )),
+        ),
+      ]).backgroundColor(ColorUtils.string2Color('#F2F3F6')),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_state.dart';
+part 'rewards_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsRepository rewardsRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsRepository {
+  DioEngine dioEngine;
+
+  RewardsRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsRepository].
+@ProviderFor(rewardsRepository)
+final rewardsRepositoryProvider = Provider<RewardsRepository>.internal(
+  rewardsRepository,
+  name: r'rewardsRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsRepositoryRef = ProviderRef<RewardsRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsState rewardsStateFromJson(String str) => RewardsState.fromJson(json.decode(str));
+
+String rewardsStateToJson(RewardsState data) => json.encode(data.toJson());
+
+class RewardsState {
+  RewardsState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsState.fromJson(Map<dynamic, dynamic> json) => RewardsState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 108 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_vm.dart

@@ -0,0 +1,108 @@
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import './rewards_state.dart';
+import './rewards_repository.dart';
+part 'rewards_vm.g.dart';
+
+@riverpod
+class RewardsVm extends _$RewardsVm {
+  late RewardsRepository rewardsRepository;
+  RewardsState initState() {
+    return RewardsState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsState build() {
+    // 引入数据仓库
+    rewardsRepository = ref.read(rewardsRepositoryProvider);
+    // 初始化状态
+    RewardsState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result =
+          await rewardsRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards/rewards_vm.g.dart

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

+ 0 - 14
packages/cpt_rewards/lib/modules/rewards/vm/rewards_view_model.dart

@@ -1,14 +0,0 @@
-
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-
-part 'rewards_view_model.g.dart';
-
-@riverpod
-class RewardsViewModel extends _$RewardsViewModel {
-
-  @override
-  void build(){
-
-  }
-
-}

+ 170 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_page.dart

@@ -0,0 +1,170 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/cupertino.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/shatter/picker_container.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_address_vm.dart';
+
+@RoutePage()
+class RewardsAddressPage extends HookConsumerWidget {
+  const RewardsAddressPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsAddressPageRoute());
+    } else {
+      appRouter.push(const RewardsAddressPageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Column(
+      children: [
+        Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const Text(
+              maxLines: 1, // 设置最大行数为2
+              overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+              'Delibowl Group',
+              style: TextStyle(
+                  fontSize: 16.0,
+                  color: Colors.black,
+                  fontWeight: FontWeight.w500),
+            ),
+            Row(
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                const MyAssetImage(
+                  Assets.rewardsRewardsIconAddes,
+                  width: 15,
+                  height: 19,
+                ).marginOnly(right: 10),
+                const Expanded(
+                  child: Text(
+                    maxLines: 2, // 设置最大行数为2
+                    overflow: TextOverflow.ellipsis,
+                    softWrap: true, // 启用自动换行
+                    '176 Orchard Rd, #02-29/30 Song Fa Bak Kut Teh The Centrepoint, Singapore 238843',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: Color.fromARGB(255, 69, 33, 33),
+                        fontWeight: FontWeight.w400),
+                  ),
+                ),
+              ],
+            ).marginOnly(top: 10, bottom: 10),
+            Container(
+              height: 40,
+              decoration: BoxDecoration(
+                color: Colors.white,
+                borderRadius: const BorderRadius.all(Radius.circular(6.0)),
+                border: Border.all(
+                    color: ColorUtils.string2Color('#4161D0'), width: 1.0),
+              ),
+              child: Center(
+                child: Text(
+                  '+65 26593458',
+                  style: TextStyle(
+                      fontSize: 15.0,
+                      color: ColorUtils.string2Color('#4161D0'),
+                      fontWeight: FontWeight.w500),
+                ),
+              ),
+            ),
+          ],
+        ),
+      ],
+    );
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      decoration: const BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.all(Radius.circular(6.0)),
+        boxShadow: [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Column(
+        children: [
+          SizedBox(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 160,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.start,
+              children: [_buildItemLeftSection(context, ref, item, _vm)],
+            ).paddingOnly(left: 20, right: 20, top: 15),
+          ).constrained(
+            minHeight: 160,
+          ),
+        ],
+      ),
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return ListView.builder(
+      itemCount: itemsList.length,
+      itemBuilder: (context, index) {
+        return _buildSaleItem(context, ref, itemsList[index], _vm);
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsAddressVmProvider.notifier);
+    final state = ref.watch(rewardsAddressVmProvider);
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Redeem Deal At",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      body: Container(
+        child: Column(
+          children: [
+            Expanded(
+              child: EasyRefresh(
+                // 上拉加载
+                onLoad: () async {
+                  Log.d("----onLoad");
+                  _vm.onLoadData();
+                },
+                // 下拉刷新
+                onRefresh: () async {
+                  Log.d("----onRefresh");
+                  _vm.refreshListData();
+                },
+                child: Container(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    padding: const EdgeInsets.only(top: 15),
+                    child: _buildSaleList(context, ref, _vm)),
+              ),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_address_state.dart';
+part 'rewards_address_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsAddressRepository rewardsAddressRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsAddressRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsAddressRepository {
+  DioEngine dioEngine;
+
+  RewardsAddressRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsAddressState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsAddressState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_address_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsAddressRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsAddressRepository].
+@ProviderFor(rewardsAddressRepository)
+final rewardsAddressRepositoryProvider = Provider<RewardsAddressRepository>.internal(
+  rewardsAddressRepository,
+  name: r'rewardsAddressRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsAddressRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsAddressRepositoryRef = ProviderRef<RewardsAddressRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsAddressState rewardsAddressStateFromJson(String str) => RewardsAddressState.fromJson(json.decode(str));
+
+String rewardsAddressStateToJson(RewardsAddressState data) => json.encode(data.toJson());
+
+class RewardsAddressState {
+  RewardsAddressState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsAddressState.fromJson(Map<dynamic, dynamic> json) => RewardsAddressState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsAddressState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsAddressState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 109 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_vm.dart

@@ -0,0 +1,109 @@
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import './rewards_address_state.dart';
+import './rewards_address_repository.dart';
+part 'rewards_address_vm.g.dart';
+
+@riverpod
+class RewardsAddressVm extends _$RewardsAddressVm {
+  late RewardsAddressRepository rewardsAddressRepository;
+  RewardsAddressState initState() {
+    return RewardsAddressState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsAddressState build() {
+    // 引入数据仓库
+    rewardsAddressRepository = ref.read(rewardsAddressRepositoryProvider);
+    // 初始化状态
+    RewardsAddressState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await rewardsAddressRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+
+
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards_address/rewards_address_vm.g.dart

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

+ 129 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_page.dart

@@ -0,0 +1,129 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/cupertino.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/shatter/picker_container.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_code_vm.dart';
+
+@RoutePage()
+class RewardsCodePage extends HookConsumerWidget {
+  const RewardsCodePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsCodePageRoute());
+    } else {
+      appRouter.push(const RewardsCodePageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Column(
+      children: [
+        Column(
+          crossAxisAlignment: CrossAxisAlignment.center,
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            const Center(
+              child: Text(
+                'SHOW THE VERIFICATION CODE TO YOUR MERCHANT',
+                textAlign: TextAlign.center,
+                style: TextStyle(
+                    fontSize: 20.0,
+                    color: Colors.black,
+                    fontWeight: FontWeight.w500),
+              ),
+            ),
+            Text(
+              'VERIFICATION CODE',
+              style: TextStyle(
+                  fontSize: 18.0,
+                  color: ColorUtils.string2Color('#54638C'),
+                  fontWeight: FontWeight.w500),
+            ).marginOnly(top: 35, bottom: 20),
+            Text(
+              '778890',
+              style: TextStyle(
+                  fontSize: 36.0,
+                  color: ColorUtils.string2Color('#4161D0'),
+                  fontWeight: FontWeight.w500),
+            ),
+          ],
+        ),
+      ],
+    );
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Column(
+      children: [
+        Container(
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(6.0)),
+            boxShadow: [
+              BoxShadow(
+                  color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+            ],
+          ),
+          width: MediaQuery.of(context).size.width - 30,
+          height: 250,
+          // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisAlignment: MainAxisAlignment.start,
+            children: [_buildItemLeftSection(context, ref, item, _vm)],
+          ).paddingOnly(left: 26, right: 26, top: 40),
+        ),
+      ],
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return _buildSaleItem(context, ref, itemsList[0], _vm);
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsCodeVmProvider.notifier);
+    final state = ref.watch(rewardsCodeVmProvider);
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Verification Code",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      body: Container(
+        child: Column(
+          children: [
+            Expanded(
+              child: 
+              EasyRefresh(
+                child: 
+                Container(
+                    color: ColorUtils.string2Color('#F2F3F6'),
+                    padding: const EdgeInsets.only(top: 15),
+                    child: _buildSaleList(context, ref, _vm)),
+              ),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_code_state.dart';
+part 'rewards_code_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsCodeRepository rewardsCodeRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsCodeRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsCodeRepository {
+  DioEngine dioEngine;
+
+  RewardsCodeRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsCodeState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsCodeState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_code_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsCodeRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsCodeRepository].
+@ProviderFor(rewardsCodeRepository)
+final rewardsCodeRepositoryProvider = Provider<RewardsCodeRepository>.internal(
+  rewardsCodeRepository,
+  name: r'rewardsCodeRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsCodeRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsCodeRepositoryRef = ProviderRef<RewardsCodeRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsCodeState rewardsCodeStateFromJson(String str) => RewardsCodeState.fromJson(json.decode(str));
+
+String rewardsCodeStateToJson(RewardsCodeState data) => json.encode(data.toJson());
+
+class RewardsCodeState {
+  RewardsCodeState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsCodeState.fromJson(Map<dynamic, dynamic> json) => RewardsCodeState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsCodeState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsCodeState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 109 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_vm.dart

@@ -0,0 +1,109 @@
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import './rewards_code_state.dart';
+import './rewards_code_repository.dart';
+part 'rewards_code_vm.g.dart';
+
+@riverpod
+class RewardsCodeVm extends _$RewardsCodeVm {
+  late RewardsCodeRepository rewardsCodeRepository;
+  RewardsCodeState initState() {
+    return RewardsCodeState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsCodeState build() {
+    // 引入数据仓库
+    rewardsCodeRepository = ref.read(rewardsCodeRepositoryProvider);
+    // 初始化状态
+    RewardsCodeState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await rewardsCodeRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+
+
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards_code/rewards_code_vm.g.dart

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

+ 144 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/dialog/account_deactivation_dialog.dart

@@ -0,0 +1,144 @@
+import 'package:cpt_rewards/modules/rewards_successful/rewards_successful_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:hooks_riverpod/hooks_riverpod.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+import '../rewards_confirm_vm.dart';
+
+class AccountDeactivationDialog extends HookConsumerWidget {
+  VoidCallback confirmAction;
+
+  AccountDeactivationDialog({
+    required this.confirmAction,
+  });
+
+  Widget CheckboxList(BuildContext context) {
+    // final List<String> items = ['苹果', '香蕉', '橙子'];
+    // final List<bool> selections = [false, false, false];
+    // return Expanded(child:ListView.builder(
+    //   itemCount: items.length,
+    //   itemBuilder: (context, index) {
+    //     return Container(
+    //       padding: EdgeInsets.symmetric(vertical: 5.0),
+    //       child: CheckboxListTile(
+    //         value: selections[index],
+    //         onChanged: (bool? val) {
+    //           print('Option 1 is now ${val ?? false}');
+    //           selections[index] = val!;
+    //         },
+    //         title: Text(items[index]),
+    //       ),
+    //     );
+    //   },
+    // )
+    // );
+    var _rangeValues = RangeValues(20.0, 80.0);
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        const Text(
+          textAlign: TextAlign.center,
+          'Are you sure to spend 600 points to redeem goods?',
+          style: TextStyle(
+              fontSize: 19.0, color: Colors.black, fontWeight: FontWeight.w500),
+        ).paddingOnly(left: 40, right: 40)
+      ],
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsConfirmVmProvider.notifier);
+    final state = ref.watch(rewardsConfirmVmProvider);
+    List itemsList = _vm.state.list.toList();
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        Container(
+          width: double.infinity,
+          height: 55,
+          decoration: BoxDecoration(
+            color: context.appColors.btnBgDefault,
+            borderRadius: const BorderRadius.only(
+              topRight: Radius.circular(15),
+              topLeft: Radius.circular(15),
+            ),
+          ),
+          child: Row(
+            children: [
+              const SizedBox(width: 45),
+              MyTextView(
+                'Points payment',
+                fontSize: 18,
+                textAlign: TextAlign.center,
+                isFontMedium: true,
+                textColor: Colors.white,
+              ).expanded(),
+              const MyAssetImage(
+                Assets.baseServiceDialogDeleteIcon,
+                width: 25,
+                height: 25.5,
+              ).onTap(() {
+                onCancel();
+              }, padding: 10)
+            ],
+          ),
+        ),
+        Container(
+          width: double.infinity,
+          padding: const EdgeInsets.only(top: 22),
+          decoration: BoxDecoration(
+            color: context.appColors.whiteSecondBG,
+            borderRadius: const BorderRadius.only(
+              bottomLeft: Radius.circular(15),
+              bottomRight: Radius.circular(15),
+            ),
+          ),
+          child: Column(
+            children: [
+              Container(height: 150, child: CheckboxList(context)),
+              Row(
+                children: [
+                  const SizedBox(width: 18),
+                  Expanded(
+                      flex: 1,
+                      child: InkWell(
+                        onTap: () async {
+                          onCancel();
+                          RewardsSuccessfulPage.startInstance();
+                          // confirmAction();
+                        },
+                        child: MyTextView(
+                          'Pay Now',
+                          fontSize: 16,
+                          paddingTop: 13,
+                          paddingBottom: 13,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: Colors.white,
+                          backgroundColor: context.appColors.btnBgDefault,
+                          cornerRadius: 7,
+                        ),
+                      )),
+                  const SizedBox(width: 18),
+                ],
+              ).marginOnly(bottom: 30, top: 28),
+            ],
+          ),
+        ),
+      ],
+    ).constrained(width: 340);
+  }
+
+//取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

+ 388 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_page.dart

@@ -0,0 +1,388 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/cupertino.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.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 'package:widgets/shatter/picker_container.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_confirm_vm.dart';
+
+@RoutePage()
+class RewardsConfirmPage extends HookConsumerWidget {
+  const RewardsConfirmPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsConfirmPageRoute());
+    } else {
+      appRouter.push(const RewardsConfirmPageRoute());
+    }
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, _vm) {
+    return Column(
+      children: [
+        Container(
+            decoration: const BoxDecoration(
+              color: Colors.white,
+              borderRadius: BorderRadius.all(Radius.circular(6.0)),
+              boxShadow: [
+                BoxShadow(
+                    color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+              ],
+            ),
+            width: MediaQuery.of(context).size.width - 30,
+            // height: 420,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.start,
+              children: [
+                const MyAssetImage(
+                  Assets.rewardsRewardsIndex1,
+                  // width: 110,
+                  height: 150,
+                ),
+                const Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    Text(
+                      maxLines: 1, // 设置最大行数为2
+                      overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+                      'Cute children multifunctional umbrella',
+                      style: TextStyle(
+                          fontSize: 17.0,
+                          color: Colors.black,
+                          fontWeight: FontWeight.w500),
+                    ),
+                  ],
+                ).paddingOnly(left: 15, right: 15, top: 10, bottom: 30),
+              ],
+            )),
+      ],
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  Widget _buildDeal(BuildContext context, WidgetRef ref, _vm) {
+    return Column(
+      children: [
+        Container(
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(6.0)),
+            boxShadow: [
+              BoxShadow(
+                  color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+            ],
+          ),
+          width: MediaQuery.of(context).size.width - 30,
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                mainAxisAlignment: MainAxisAlignment.start,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  const MyAssetImage(
+                    Assets.rewardsRewardsDetailDeal,
+                    width: 25,
+                    height: 25,
+                  ).marginOnly(right: 5),
+                  Text(
+                    'Redeem Deal At',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#000000'),
+                        fontWeight: FontWeight.w500),
+                  )
+                ],
+              ),
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Text(
+                    'Also redeemable in 1 more location',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#54638C'),
+                        fontWeight: FontWeight.w400),
+                  ),
+                ],
+              ).marginOnly(top: 10, bottom: 15),
+              Container(
+                height: 40,
+                decoration: BoxDecoration(
+                  color: Colors.white,
+                  borderRadius: const BorderRadius.all(Radius.circular(6.0)),
+                  border: Border.all(
+                      color: ColorUtils.string2Color('#4161D0'), width: 1.0),
+                ),
+                child: Center(
+                  child: Text(
+                    'See More Locations',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#4161D0'),
+                        fontWeight: FontWeight.w500),
+                  ),
+                ),
+              ),
+            ],
+          ).paddingOnly(left: 15, right: 15, top: 12, bottom: 20),
+        ),
+      ],
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  Widget _buildPackage(BuildContext context, WidgetRef ref, _vm) {
+    return Column(
+      children: [
+        Container(
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(6.0)),
+            boxShadow: [
+              BoxShadow(
+                  color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+            ],
+          ),
+          width: MediaQuery.of(context).size.width - 30,
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Row(
+                mainAxisSize: MainAxisSize.min,
+                mainAxisAlignment: MainAxisAlignment.start,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  const MyAssetImage(
+                    Assets.rewardsRewardsIconDatd,
+                    width: 15,
+                    height: 15,
+                  ).marginOnly(right: 10),
+                  Text(
+                    'Redeem From',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#000000'),
+                        fontWeight: FontWeight.w500),
+                  )
+                ],
+              ).marginOnly(bottom: 10),
+              Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    '17 Mar 2020 until 15 Jul 2020',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#54638C'),
+                        fontWeight: FontWeight.w400),
+                  ),
+                ],
+              ),
+            ],
+          ).paddingOnly(left: 15, right: 15, top: 12, bottom: 20),
+        ),
+      ],
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  Widget _buildNotice(BuildContext context, WidgetRef ref, _vm) {
+    return Column(
+      children: [
+        Container(
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(6.0)),
+            boxShadow: [
+              BoxShadow(
+                  color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+            ],
+          ),
+          width: MediaQuery.of(context).size.width - 30,
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Text(
+                    'Quantity:',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#333333'),
+                        fontWeight: FontWeight.w400),
+                  ),
+                  Row(
+                    children: [
+                      const MyAssetImage(
+                        Assets.rewardsRewardsJian,
+                        width: 21,
+                        height: 21,
+                      ),
+                      Text(
+                        '2',
+                        style: TextStyle(
+                            fontSize: 19.0,
+                            color: ColorUtils.string2Color('#333333'),
+                            fontWeight: FontWeight.w500),
+                      ).marginOnly(left: 15, right: 15),
+                      const MyAssetImage(
+                        Assets.rewardsRewardsJia,
+                        width: 21,
+                        height: 21,
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Text(
+                    'Points:',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#333333'),
+                        fontWeight: FontWeight.w400),
+                  ),
+                  Row(
+                    children: [
+                      Text(
+                        '350',
+                        style: TextStyle(
+                            decoration: TextDecoration.lineThrough,
+                            decorationColor: ColorUtils.string2Color('#54638C'),
+                            decorationStyle: TextDecorationStyle.solid,
+                            fontSize: 14.0,
+                            color: ColorUtils.string2Color('#54638C'),
+                            fontWeight: FontWeight.w400),
+                      ),
+                      Text(
+                        '300',
+                        style: TextStyle(
+                            fontSize: 19.0,
+                            color: ColorUtils.string2Color('#333333'),
+                            fontWeight: FontWeight.w500),
+                      ).marginOnly(left: 10),
+                    ],
+                  ),
+                ],
+              ).marginOnly(top: 30, bottom: 30),
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Text(
+                    'Amount:',
+                    style: TextStyle(
+                        fontSize: 15.0,
+                        color: ColorUtils.string2Color('#333333'),
+                        fontWeight: FontWeight.w400),
+                  ),
+                  Row(
+                    children: [
+                      Text(
+                        '600',
+                        style: TextStyle(
+                            fontSize: 19.0,
+                            color: ColorUtils.string2Color('#4161D0'),
+                            fontWeight: FontWeight.w500),
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ],
+          ).paddingOnly(left: 15, right: 15, top: 30, bottom: 30),
+        ),
+      ],
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsConfirmVmProvider.notifier);
+    final state = ref.watch(rewardsConfirmVmProvider);
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Verification Confirm",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      body: Column(
+        children: [
+          Expanded(
+              child: SingleChildScrollView(
+                  scrollDirection: Axis.vertical,
+                  physics: const BouncingScrollPhysics(),
+                  clipBehavior: Clip.none,
+                  child: Column(
+                    children: [
+                      Container(
+                          color: ColorUtils.string2Color('#F2F3F6'),
+                          padding: const EdgeInsets.only(top: 15),
+                          child: Column(
+                            children: [
+                              _buildSaleItem(context, ref, _vm),
+                              _buildDeal(context, ref, _vm),
+                              _buildPackage(context, ref, _vm),
+                              _buildNotice(context, ref, _vm),
+                            ],
+                          )),
+                    ],
+                  ))),
+          Container(
+            height: 50,
+            color: ColorUtils.string2Color('#4161D0'),
+            child: Flex(
+              direction: Axis.horizontal,
+              children: [
+                Expanded(
+                  flex: 1,
+                  child: Container(
+                    color: ColorUtils.string2Color('#4161D0'),
+                    height: 100,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      crossAxisAlignment: CrossAxisAlignment.center,
+                      children: [
+                        MyTextView(
+                          "Redeem",
+                          fontSize: 16,
+                          textColor: Colors.white,
+                          isFontMedium: true,
+                        ),
+                      ],
+                    ),
+                  ).onTap(() {
+                    // 去详情
+                    _vm.doDeleteAccount();
+                  }),
+                ),
+              ],
+            ),
+          )
+        ],
+      ),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_confirm_state.dart';
+part 'rewards_confirm_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsConfirmRepository rewardsConfirmRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsConfirmRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsConfirmRepository {
+  DioEngine dioEngine;
+
+RewardsConfirmRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+      final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsConfirmState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsConfirmState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_confirm_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsConfirmRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsConfirmRepository].
+@ProviderFor(rewardsConfirmRepository)
+final rewardsConfirmRepositoryProvider = Provider<RewardsConfirmRepository>.internal(
+  rewardsConfirmRepository,
+  name: r'rewardsConfirmRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsConfirmRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsConfirmRepositoryRef = ProviderRef<RewardsConfirmRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsConfirmState rewardsConfirmStateFromJson(String str) => RewardsConfirmState.fromJson(json.decode(str));
+
+String rewardsConfirmStateToJson(RewardsConfirmState data) => json.encode(data.toJson());
+
+class RewardsConfirmState {
+  RewardsConfirmState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsConfirmState.fromJson(Map<dynamic, dynamic> json) => RewardsConfirmState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsConfirmState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsConfirmState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 118 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_vm.dart

@@ -0,0 +1,118 @@
+import 'package:cpt_rewards/modules/rewards_confirm/dialog/account_deactivation_dialog.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import './rewards_confirm_state.dart';
+import './rewards_confirm_repository.dart';
+part 'rewards_confirm_vm.g.dart';
+
+@riverpod
+class RewardsConfirmVm extends _$RewardsConfirmVm {
+  late RewardsConfirmRepository rewardsConfirmRepository;
+  RewardsConfirmState initState() {
+    return RewardsConfirmState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsConfirmState build() {
+    // 引入数据仓库
+    rewardsConfirmRepository = ref.read(rewardsConfirmRepositoryProvider);
+    // 初始化状态
+    RewardsConfirmState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsConfirm(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result =
+          await rewardsConfirmRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+
+  void doDeleteAccount() {
+    DialogEngine.show(widget: AccountDeactivationDialog(
+      confirmAction: () {
+        ToastEngine.show("点击了确定");
+      },
+    ));
+  }
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards_confirm/rewards_confirm_vm.g.dart

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

File diff suppressed because it is too large
+ 632 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_page.dart


+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_detail_state.dart';
+part 'rewards_detail_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsDetailRepository rewardsDetailRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsDetailRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsDetailRepository {
+  DioEngine dioEngine;
+
+  RewardsDetailRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsDetailState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsDetailState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_detail_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsDetailRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsDetailRepository].
+@ProviderFor(rewardsDetailRepository)
+final rewardsDetailRepositoryProvider = Provider<RewardsDetailRepository>.internal(
+  rewardsDetailRepository,
+  name: r'rewardsDetailRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsDetailRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsDetailRepositoryRef = ProviderRef<RewardsDetailRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsDetailState rewardsDetailStateFromJson(String str) => RewardsDetailState.fromJson(json.decode(str));
+
+String rewardsDetailStateToJson(RewardsDetailState data) => json.encode(data.toJson());
+
+class RewardsDetailState {
+  RewardsDetailState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsDetailState.fromJson(Map<dynamic, dynamic> json) => RewardsDetailState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsDetailState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsDetailState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 109 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_vm.dart

@@ -0,0 +1,109 @@
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import './rewards_detail_state.dart';
+import './rewards_detail_repository.dart';
+part 'rewards_detail_vm.g.dart';
+
+@riverpod
+class RewardsDetailVm extends _$RewardsDetailVm {
+  late RewardsDetailRepository rewardsDetailRepository;
+  RewardsDetailState initState() {
+    return RewardsDetailState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsDetailState build() {
+    // 引入数据仓库
+    rewardsDetailRepository = ref.read(rewardsDetailRepositoryProvider);
+    // 初始化状态
+    RewardsDetailState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await rewardsDetailRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+
+
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards_detail/rewards_detail_vm.g.dart

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

+ 130 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_page.dart

@@ -0,0 +1,130 @@
+import 'package:cpt_rewards/modules/rewards_code/rewards_code_page.dart';
+import 'package:cpt_rewards/modules/rewards_redeem/rewards_redeem_page.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_history_earned_vm.dart';
+
+@RoutePage()
+class RewardsHistoryEarnedPage extends HookConsumerWidget {
+  const RewardsHistoryEarnedPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsHistoryEarnedPageRoute());
+    } else {
+      appRouter.push(const RewardsHistoryEarnedPageRoute());
+    }
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      padding: const EdgeInsets.only(top: 15, bottom: 15, left: 18, right: 18),
+      decoration: BoxDecoration(
+          border: Border(
+              bottom: BorderSide(
+        width: 1.0, // 底边边框的宽度
+        color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+      ))),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              Text(
+                'Daily Login',
+                style: TextStyle(
+                    fontSize: 15.0,
+                    color: ColorUtils.string2Color('#000000'),
+                    fontWeight: FontWeight.w500), // 设置字体大小
+              ).marginOnly(bottom: 6),
+              Text(
+                '14 Oct 2024  10:00PM',
+                style: TextStyle(
+                    fontSize: 13.0,
+                    color: ColorUtils.string2Color('#808DAF'),
+                    fontWeight: FontWeight.w400), // 设置字体大小
+              ),
+            ],
+          ),
+          Text(
+            '+2',
+            style: TextStyle(
+                fontSize: 20.0,
+                color: ColorUtils.string2Color('#FDB429'),
+                fontWeight: FontWeight.w500), // 设置字体大小
+          ),
+        ],
+      ),
+    );
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return Container(
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.circular(10),
+          boxShadow: const [
+            BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+          ],
+        ),
+        child:
+            // Column(
+            //     crossAxisAlignment: CrossAxisAlignment.center,
+            //     mainAxisAlignment: MainAxisAlignment.center,
+            //     children: [
+            ListView.builder(
+          itemCount: itemsList.length,
+          itemBuilder: (context, index) {
+            return _buildSaleItem(context, ref, itemsList[index], _vm);
+          },
+        )
+        // ])
+        );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsHistoryEarnedVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("资产")),
+      body: Container(
+        color: ColorUtils.string2Color('#F2F3F6'),
+        padding: const EdgeInsets.only(top: 15, left: 15, right: 15),
+        child: EasyRefresh(
+          // 上拉加载
+          onLoad: () async {
+            Log.d("----onLoad");
+            _vm.onLoadData();
+          },
+          // 下拉刷新
+          onRefresh: () async {
+            Log.d("----onRefresh");
+            _vm.refreshListData();
+          },
+          child: Container(
+              // color: ColorUtils.string2Color('#F2F3F6'),
+              // padding: const EdgeInsets.only(top: 15, left: 15, right: 15),
+              child: _buildSaleList(context, ref, _vm)),
+        ),
+      ),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_history_earned_state.dart';
+part 'rewards_history_earned_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsHistoryEarnedRepository rewardsHistoryEarnedRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsHistoryEarnedRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsHistoryEarnedRepository {
+  DioEngine dioEngine;
+
+  RewardsHistoryEarnedRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsHistoryEarnedState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsHistoryEarnedState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_history_earned_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsHistoryEarnedRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsHistoryEarnedRepository].
+@ProviderFor(rewardsHistoryEarnedRepository)
+final rewardsHistoryEarnedRepositoryProvider = Provider<RewardsHistoryEarnedRepository>.internal(
+  rewardsHistoryEarnedRepository,
+  name: r'rewardsHistoryEarnedRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsHistoryEarnedRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsHistoryEarnedRepositoryRef = ProviderRef<RewardsHistoryEarnedRepository>;
+// 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

+ 49 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+RewardsHistoryEarnedState rewardsHistoryEarnedStateFromJson(String str) => RewardsHistoryEarnedState.fromJson(json.decode(str));
+
+String rewardsHistoryEarnedStateToJson(RewardsHistoryEarnedState data) => json.encode(data.toJson());
+
+class RewardsHistoryEarnedState {
+  RewardsHistoryEarnedState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory RewardsHistoryEarnedState.fromJson(Map<dynamic, dynamic> json) => RewardsHistoryEarnedState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  RewardsHistoryEarnedState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return RewardsHistoryEarnedState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 105 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_vm.dart

@@ -0,0 +1,105 @@
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import './rewards_history_earned_state.dart';
+import './rewards_history_earned_repository.dart';
+part 'rewards_history_earned_vm.g.dart';
+
+@riverpod
+class RewardsHistoryEarnedVm extends _$RewardsHistoryEarnedVm {
+  late RewardsHistoryEarnedRepository rewardsHistoryEarnedRepository;
+  RewardsHistoryEarnedState initState() {
+    return RewardsHistoryEarnedState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  RewardsHistoryEarnedState build() {
+    // 引入数据仓库
+    rewardsHistoryEarnedRepository = ref.read(rewardsHistoryEarnedRepositoryProvider);
+    // 初始化状态
+    RewardsHistoryEarnedState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await rewardsHistoryEarnedRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+}

+ 25 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_earned/rewards_history_earned_vm.g.dart

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

+ 124 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_page.dart

@@ -0,0 +1,124 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+// ignore: depend_on_referenced_packages
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
+
+import '../../router/page/rewards_page_router.dart';
+import './rewards_history_vm.dart';
+
+@RoutePage()
+class RewardsHistoryPage extends HookConsumerWidget {
+  const RewardsHistoryPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsHistoryPageRoute());
+    } else {
+      appRouter.push(const RewardsHistoryPageRoute());
+    }
+  }
+
+  // 顶部tab 切换
+  Widget _buildTopSection(
+      BuildContext context, WidgetRef ref, _vm, tabsRouter) {
+    final topSectionsData = _vm.topSectionsData;
+    final currentTabIdx = tabsRouter.activeIndex;
+    return Container(
+      color: ColorUtils.string2Color('#F2F3F6'),
+      child: Center(
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: List.generate(topSectionsData.length, (index) {
+            final item = topSectionsData[index];
+            return Container(
+              width:
+                  MediaQuery.of(context).size.width / topSectionsData.length -
+                      45,
+              height: 43,
+              padding: const EdgeInsets.only(
+                  top: 10, bottom: 10, left: 10, right: 10),
+              decoration: index == currentTabIdx
+                  ? BoxDecoration(
+                      color: index == currentTabIdx
+                          ? context.appColors.btnBgDefault
+                          : ColorUtils.string2Color("#F2F3F6"),
+                      borderRadius: BorderRadius.circular(20),
+                      boxShadow: [
+                        BoxShadow(
+                          color: Colors.grey.withOpacity(0.5),
+                          spreadRadius: 1,
+                          blurRadius: 5,
+                          offset:
+                              const Offset(0, 2), // changes position of shadow
+                        ),
+                      ],
+                    )
+                  : null,
+              child: Row(
+                children: [
+                  Expanded(
+                    child: Container(
+                      alignment: Alignment.center,
+                      child: MyTextView(
+                        item['title'],
+                        fontSize: 16,
+                        textAlign: TextAlign.center,
+                        isFontMedium: true,
+                        textColor: index == currentTabIdx
+                            ? Colors.white
+                            : ColorUtils.string2Color("#000000"),
+                      ),
+                    ).onTap(
+                      () {
+                        tabsRouter.setActiveIndex(index);
+                      },
+                      type: ClickType.throttle,
+                    ),
+                  ),
+                ],
+              ),
+            ).marginOnly(left: 20, right: 0, top: 15, bottom: 5);
+          }),
+        ),
+      ),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsHistoryVmProvider.notifier);
+    return Scaffold(
+        appBar: MyAppBar.appBar(
+          context,
+          "Points History",
+          backgroundColor: context.appColors.whiteBG,
+        ),
+        body: AutoTabsRouter.pageView(
+          routes: const [
+            RewardsHistoryEarnedPageRoute(),
+            RewardsHistorySpentPageRoute(),
+          ],
+          builder: (context, child, pageController) {
+            final tabsRouter = AutoTabsRouter.of(context);
+            return Column(
+              children: [
+                _buildTopSection(context, ref, _vm, tabsRouter),
+                Expanded(
+                  child: child,
+                ),
+              ],
+            );
+          },
+        ));
+  }
+}

+ 129 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_page.dart

@@ -0,0 +1,129 @@
+import 'package:cpt_rewards/modules/rewards_transaction/rewards_transaction_page.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/rewards_page_router.dart';
+import './rewards_history_spent_vm.dart';
+
+@RoutePage()
+class RewardsHistorySpentPage extends HookConsumerWidget {
+  const RewardsHistorySpentPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const RewardsHistorySpentPageRoute());
+    } else {
+      appRouter.push(const RewardsHistorySpentPageRoute());
+    }
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      padding: const EdgeInsets.only(top: 15, bottom: 15, left: 18, right: 18),
+      decoration: BoxDecoration(
+          border: Border(
+              bottom: BorderSide(
+        width: 1.0, // 底边边框的宽度
+        color: ColorUtils.string2Color('#F2F3F6'), // 底边边框的颜色
+      ))),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              Text(
+                'Daily Login',
+                style: TextStyle(
+                    fontSize: 15.0,
+                    color: ColorUtils.string2Color('#000000'),
+                    fontWeight: FontWeight.w500), // 设置字体大小
+              ).marginOnly(bottom: 6),
+              Text(
+                '14 Oct 2024  10:00PM',
+                style: TextStyle(
+                    fontSize: 13.0,
+                    color: ColorUtils.string2Color('#808DAF'),
+                    fontWeight: FontWeight.w400), // 设置字体大小
+              ),
+            ],
+          ),
+          Text(
+            '-4.500',
+            style: TextStyle(
+                fontSize: 20.0,
+                color: ColorUtils.string2Color('#4161D0'),
+                fontWeight: FontWeight.w500), // 设置字体大小
+          ),
+        ],
+      ),
+    );
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return Container(
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.circular(10),
+          boxShadow: const [
+            BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+          ],
+        ),
+        child:
+            // Column(
+            //     crossAxisAlignment: CrossAxisAlignment.center,
+            //     mainAxisAlignment: MainAxisAlignment.center,
+            //     children: [
+            ListView.builder(
+          itemCount: itemsList.length,
+          itemBuilder: (context, index) {
+            return _buildSaleItem(context, ref, itemsList[index], _vm);
+          },
+        )
+        // ])
+        );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(rewardsHistorySpentVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("资产")),
+      body: Container(
+        color: ColorUtils.string2Color('#F2F3F6'),
+        padding: const EdgeInsets.only(top: 15, left: 15, right: 15),
+        child: EasyRefresh(
+          // 上拉加载
+          onLoad: () async {
+            Log.d("----onLoad");
+            _vm.onLoadData();
+          },
+          // 下拉刷新
+          onRefresh: () async {
+            Log.d("----onRefresh");
+            _vm.refreshListData();
+          },
+          child: Container(
+              // color: ColorUtils.string2Color('#F2F3F6'),
+              // padding: const EdgeInsets.only(top: 15, left: 15, right: 15),
+              child: _buildSaleList(context, ref, _vm)),
+        ),
+      ),
+    );
+  }
+}

+ 70 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import './rewards_history_spent_state.dart';
+part 'rewards_history_spent_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+RewardsHistorySpentRepository rewardsHistorySpentRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return RewardsHistorySpentRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class RewardsHistorySpentRepository {
+  DioEngine dioEngine;
+
+  RewardsHistorySpentRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = RewardsHistorySpentState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<RewardsHistorySpentState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'rewards_history_spent_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$rewardsHistorySpentRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [rewardsHistorySpentRepository].
+@ProviderFor(rewardsHistorySpentRepository)
+final rewardsHistorySpentRepositoryProvider = Provider<RewardsHistorySpentRepository>.internal(
+  rewardsHistorySpentRepository,
+  name: r'rewardsHistorySpentRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$rewardsHistorySpentRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef RewardsHistorySpentRepositoryRef = ProviderRef<RewardsHistorySpentRepository>;
+// 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

+ 0 - 0
packages/cpt_rewards/lib/modules/rewards_history/rewards_history_spent/rewards_history_spent_state.dart


Some files were not shown because too many files changed in this diff