Explorar o código

Merge branch 'dev' of http://git.wmzhubo.com/guadoutech/YYHome into dev

glglove hai 2 semanas
pai
achega
8fc3062e37
Modificáronse 100 ficheiros con 6289 adicións e 143 borrados
  1. 253 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart
  2. 54 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart
  3. 103 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart
  4. 27 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart
  5. 74 0
      packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart
  6. 215 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart
  7. 18 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart
  8. 15 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart
  9. 27 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart
  10. 4 1
      packages/cpt_main/lib/modules/feedback/history/feedback_history.dart
  11. 1 1
      packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.g.dart
  12. 2 1
      packages/cpt_main/lib/modules/feedback/item_feedback.dart
  13. 4 1
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart
  14. 1 1
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.g.dart
  15. 2 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_large.dart
  16. 3 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_small.dart
  17. 9 7
      packages/cpt_main/lib/modules/home/home_view_model.dart
  18. 1 1
      packages/cpt_main/lib/modules/home/home_view_model.g.dart
  19. 55 0
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_screen.dart
  20. 31 0
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_state.dart
  21. 130 0
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.dart
  22. 27 0
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.g.dart
  23. 54 0
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_screen.dart
  24. 31 0
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_state.dart
  25. 130 0
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.dart
  26. 28 0
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.g.dart
  27. 152 0
      packages/cpt_main/lib/modules/home/latest_news/latest_news_page.dart
  28. 54 0
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_screen.dart
  29. 31 0
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_state.dart
  30. 131 0
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.dart
  31. 28 0
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.g.dart
  32. 54 0
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_screen.dart
  33. 31 0
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_state.dart
  34. 130 0
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.dart
  35. 28 0
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.g.dart
  36. 56 0
      packages/cpt_main/lib/modules/home/management_guides/item_management_guide.dart
  37. 84 0
      packages/cpt_main/lib/modules/home/management_guides/management_guides_page.dart
  38. 32 0
      packages/cpt_main/lib/modules/home/management_guides/management_guides_state.dart
  39. 144 0
      packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.dart
  40. 28 0
      packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.g.dart
  41. 4 0
      packages/cpt_main/lib/modules/home/management_guides/test_guide_bean.dart
  42. 72 0
      packages/cpt_main/lib/modules/home/property_news/home_property_news_page.dart
  43. 31 0
      packages/cpt_main/lib/modules/home/property_news/home_property_news_state.dart
  44. 130 0
      packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.dart
  45. 28 0
      packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.g.dart
  46. 68 0
      packages/cpt_main/lib/modules/home/property_news/item_list_news.dart
  47. 210 28
      packages/cpt_main/lib/modules/me/me_page.dart
  48. 46 0
      packages/cpt_main/lib/modules/me/me_view_model.dart
  49. 25 0
      packages/cpt_main/lib/modules/me/me_view_model.g.dart
  50. 99 0
      packages/cpt_main/lib/modules/notification/item_notification.dart
  51. 26 0
      packages/cpt_main/lib/modules/notification/item_notification_header.dart
  52. 6 0
      packages/cpt_main/lib/modules/notification/notification_group_data.dart
  53. 78 7
      packages/cpt_main/lib/modules/notification/notification_page.dart
  54. 31 0
      packages/cpt_main/lib/modules/notification/notification_state.dart
  55. 160 0
      packages/cpt_main/lib/modules/notification/notification_view_model.dart
  56. 27 0
      packages/cpt_main/lib/modules/notification/notification_view_model.g.dart
  57. 3 1
      packages/cpt_main/lib/modules/visitor/now/visitor_now_large.dart
  58. 3 1
      packages/cpt_main/lib/modules/visitor/now/visitor_now_small.dart
  59. 296 0
      packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart
  60. 72 0
      packages/cpt_main/lib/modules/visitor/register/visitor_register_state.dart
  61. 137 0
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart
  62. 27 0
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.g.dart
  63. 28 0
      packages/cpt_main/lib/router/page/main_page_router.dart
  64. 220 0
      packages/cpt_main/lib/router/page/main_page_router.gr.dart
  65. 126 0
      packages/cpt_notice_board/lib/modules/announ/page/announ_page.dart
  66. 49 0
      packages/cpt_notice_board/lib/modules/announ/page/announ_state.dart
  67. 70 0
      packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.dart
  68. 27 0
      packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.g.dart
  69. 112 0
      packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.dart
  70. 26 0
      packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.g.dart
  71. 148 0
      packages/cpt_notice_board/lib/modules/documents/page/documents_page.dart
  72. 49 0
      packages/cpt_notice_board/lib/modules/documents/page/documents_state.dart
  73. 70 0
      packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.dart
  74. 28 0
      packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.g.dart
  75. 105 0
      packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.dart
  76. 25 0
      packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.g.dart
  77. 130 0
      packages/cpt_notice_board/lib/modules/event/page/event_page.dart
  78. 49 0
      packages/cpt_notice_board/lib/modules/event/page/event_state.dart
  79. 70 0
      packages/cpt_notice_board/lib/modules/event/repository/event_repository.dart
  80. 27 0
      packages/cpt_notice_board/lib/modules/event/repository/event_repository.g.dart
  81. 105 0
      packages/cpt_notice_board/lib/modules/event/vm/event_vm.dart
  82. 25 0
      packages/cpt_notice_board/lib/modules/event/vm/event_vm.g.dart
  83. 148 67
      packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart
  84. 99 2
      packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.dart
  85. 9 10
      packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.g.dart
  86. 25 4
      packages/cpt_notice_board/lib/router/page/notice_board_page_router.dart
  87. 61 1
      packages/cpt_notice_board/lib/router/page/notice_board_page_router.gr.dart
  88. 32 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart
  89. 3 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart
  90. 13 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart
  91. 26 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.g.dart
  92. 32 0
      packages/cpt_profile/lib/modules/my_household/my_household_page.dart
  93. 3 0
      packages/cpt_profile/lib/modules/my_household/my_household_state.dart
  94. 13 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart
  95. 27 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.g.dart
  96. 210 4
      packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart
  97. 133 0
      packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart
  98. 49 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart
  99. 56 3
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart
  100. 0 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.g.dart

+ 253 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart

@@ -0,0 +1,253 @@
+import 'package:cpt_main/modules/feedback/create/feedback_create_state.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:plugin_platform/engine/image/image_nine_grid.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_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/picker_container.dart';
+import 'package:widgets/widget_export.dart';
+import '../../../router/page/main_page_router.dart';
+import 'feedback_create_view_model.dart';
+
+@RoutePage()
+class FeedbackCreatePage extends HookConsumerWidget {
+  const FeedbackCreatePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const FeedbackCreatePageRoute());
+    } else {
+      appRouter.push(const FeedbackCreatePageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(feedbackCreateViewModelProvider.notifier);
+    final state = ref.watch(feedbackCreateViewModelProvider);
+    final noteCount = useState(0);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.create_new_feedback),
+      backgroundColor: context.appColors.whiteBG,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 15),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //选择类型
+              FormRequireText(
+                text: S.current.full_name,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 选择器
+              PickerContainer(
+                content: state.selectedOption ?? "",
+                hint: S.current.choose_category,
+                margin: const EdgeInsets.only(top: 16),
+                onClick: viewModel.pickCategory,
+              ),
+
+              //Title
+              FormRequireText(
+                text: S.current.title,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                "title",
+                marginTop: 16,
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                errorText: state.titleErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['desc']!['focusNode']);
+                },
+              ),
+
+              // DESC
+              MyTextView(
+                S.current.describe_your_feedback,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+              //大文本框
+              IgnoreKeyboardDismiss(
+                child: Container(
+                  height: 177,
+                  margin: const EdgeInsets.only(top: 16),
+                  padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                  decoration: BoxDecoration(
+                    color: context.appColors.authFiledBG,
+                    borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  ),
+                  child: Stack(
+                    children: [
+                      TextField(
+                        cursorColor: context.appColors.authFiledText,
+                        cursorWidth: 1.5,
+                        autofocus: false,
+                        enabled: true,
+                        focusNode: state.formData["desc"]!['focusNode'],
+                        controller: state.formData["desc"]!['controller'],
+                        decoration: InputDecoration(
+                          isDense: true,
+                          isCollapsed: true,
+                          border: InputBorder.none,
+                          hintText: state.formData["desc"]!['hintText'],
+                          hintStyle: TextStyle(
+                            color: context.appColors.authFiledHint,
+                            fontSize: 16.0,
+                            fontWeight: FontWeight.w500,
+                          ),
+                        ),
+                        style: TextStyle(
+                          color: context.appColors.authFiledText,
+                          fontSize: 16.0,
+                          fontWeight: FontWeight.w500,
+                        ),
+                        textInputAction: TextInputAction.done,
+                        onSubmitted: (value) {
+                          FocusScope.of(context).unfocus();
+                        },
+                        maxLines: null,
+                        expands: true,
+                        onChanged: (text) {
+                          // 当文本改变时,更新字符数量
+                          noteCount.value = text.length;
+                        },
+                      ),
+                      Positioned(
+                        bottom: 0.0,
+                        right: 0.0,
+                        child: Text(
+                          S.current.characters(noteCount.value),
+                          style: TextStyle(
+                            color: context.appColors.textBlack,
+                            fontSize: 15.0,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+
+              MyTextView(
+                S.current.upload_pictures,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+
+              MyTextView(
+                S.current.up_to_max_images,
+                fontSize: 13,
+                marginTop: 5,
+                marginBottom: 14,
+                isFontRegular: true,
+                textColor: context.appColors.textDarkGray999,
+              ),
+
+              ImageNineGrid(
+                isSelectEnable: true,
+                maxImages: 10,
+                spacing: 10,
+                aspectRatio: 108 / 80,
+                initialImages: state.imgList,
+                onImagesChanged: (list) {
+                  viewModel.setImgList(list);
+                },
+              ),
+
+              MyButton(
+                onPressed: viewModel.submitFeedback,
+                text: S.current.submit,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 25, bottom: 25),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    FeedbackCreateState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    bool enable = true,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        enabled: enable,
+        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,
+      ),
+    );
+  }
+}

+ 54 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart

@@ -0,0 +1,54 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class FeedbackCreateState {
+//表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  //表单的错误信息展示
+  String? titleErrorText;
+
+  //类型选项
+  final List<String> optionList = ["条件1", "条件2", "条件3", "条件4"];
+  String? selectedOption;
+
+  //选择的图片
+  List<String> imgList;
+
+  // ===================================  Begin  ↓  ===================================
+
+  FeedbackCreateState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.titleErrorText,
+    required this.imgList,
+    this.selectedOption,
+  }) : formData = formData ??
+            {
+              'title': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'desc': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'hintText': S.current.type_here,
+                'obsecure': false,
+              },
+            };
+
+  FeedbackCreateState copyWith({
+    String? titleErrorText,
+    String? selectedOption,
+    List<String>? imgList,
+  }) {
+    return FeedbackCreateState(
+      formData: this.formData,
+      titleErrorText: titleErrorText,
+      imgList: imgList ?? this.imgList,
+      selectedOption: selectedOption ?? this.selectedOption,
+    );
+  }
+}

+ 103 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart

@@ -0,0 +1,103 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+
+import '../../main/main_page.dart';
+import '../create_success/feedback_create_success_page.dart';
+import 'feedback_create_state.dart';
+
+part 'feedback_create_view_model.g.dart';
+
+@riverpod
+class FeedbackCreateViewModel extends _$FeedbackCreateViewModel {
+  @override
+  FeedbackCreateState build() {
+    final state = FeedbackCreateState(imgList: []);
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+
+    return state;
+  }
+
+  //选择选项
+  void pickCategory() {
+    _dismissKeyboard();
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.optionList,
+      initialSelectIndex: 0,
+      onPickerChanged: (_, index) {
+        state = state.copyWith(selectedOption: state.optionList[index]);
+      },
+    );
+  }
+
+  void _dismissKeyboard() {
+    final FocusNode titleFocusNode = state.formData['title']!['focusNode'];
+    final FocusNode descFocusNode = state.formData['desc']!['focusNode'];
+    titleFocusNode.unfocus();
+    descFocusNode.unfocus();
+  }
+
+  ///提交反馈
+  void submitFeedback() {
+    state = state.copyWith(titleErrorText: null);
+
+    _dismissKeyboard();
+
+    final TextEditingController titleController = state.formData['title']!['controller'];
+    final TextEditingController descController = state.formData['desc']!['controller'];
+
+    final title = titleController.text;
+    final desc = descController.text;
+
+    Log.d('当前待提交的 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
+
+    if (Utils.isEmpty(state.selectedOption)) {
+      ToastEngine.show(S.current.choose_category);
+      return;
+    }
+
+    if (Utils.isEmpty(title)) {
+      state = state.copyWith(titleErrorText: "Title cannot be empty!");
+      return;
+    }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
+
+    //去成功页面
+    FeedbackCreateSuccessPage.startInstance();
+  }
+
+  //选中图片
+  void setImgList(List<String> list) {
+    state = state.copyWith(imgList: list);
+  }
+
+  //初始化监听
+  void initListener(FeedbackCreateState initState) {
+    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
+
+    titleFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (titleFocusNode.hasFocus) {
+        state = state.copyWith(titleErrorText: null);
+      }
+    });
+  }
+
+  //销毁资源
+  void onDispose(FeedbackCreateState initState) {
+    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
+    titleFocusNode.dispose();
+
+    Log.d("FeedbackCreateViewModel 销毁 onDispose");
+  }
+}

+ 27 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart

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

+ 74 - 0
packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart

@@ -0,0 +1,74 @@
+import 'package:cpt_main/modules/demo_page.dart';
+import 'package:cpt_main/modules/main/main_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/main_page_router.dart';
+
+@RoutePage()
+class FeedbackCreateSuccessPage extends HookConsumerWidget {
+  const FeedbackCreateSuccessPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.popAndPush(const FeedbackCreateSuccessPageRoute());
+    } else {
+      appRouter.popAndPush(const FeedbackCreateSuccessPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.published_successfully),
+      backgroundColor: context.appColors.whiteBG,
+      body: Column(
+        children: [
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              const MyAssetImage(Assets.mainSuccessIcon, width: 54, height: 54),
+              MyTextView(
+                S.current.published_successful_txt,
+                marginTop: 12,
+                marginLeft: 55,
+                textAlign: TextAlign.center,
+                marginRight: 55,
+                fontSize: 18,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+            ],
+          ).marginOnly(top: 68),
+
+          const Spacer(),
+
+          MyButton(
+            onPressed: () {
+              MainPage.startInstance(context: context);
+            },
+            text: S.current.back_home,
+            textColor: Colors.white,
+            backgroundColor: context.appColors.btnBgDefault,
+            fontWeight: FontWeight.w500,
+            type: ClickType.throttle,
+            fontSize: 16,
+            minHeight: 50,
+            radius: 0,
+          )
+        ],
+      ),
+    );
+  }
+}

+ 215 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart

@@ -0,0 +1,215 @@
+import 'package:cpt_main/modules/demo_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/image/image_nine_grid.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/main_page_router.dart';
+import 'feedback_detail_view_model.dart';
+
+@RoutePage()
+class FeedbackDetailPage extends HookConsumerWidget {
+  const FeedbackDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const FeedbackDetailPageRoute());
+    } else {
+      appRouter.push(const FeedbackDetailPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(feedbackDetailViewModelProvider.notifier);
+    final state = ref.watch(feedbackDetailViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.feedback_details, showBottomDivider: true),
+      backgroundColor: context.appColors.backgroundDark,
+      body: SingleChildScrollView(
+          scrollDirection: Axis.vertical,
+          physics: const BouncingScrollPhysics(),
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Container(
+                color: context.appColors.whiteBG,
+                width: double.infinity,
+                padding: const EdgeInsets.symmetric(horizontal: 10),
+                height: 85,
+                child: Column(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      "Exchange old houses for new ones",
+                      fontSize: 21,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    MyTextView(
+                      "18 Sep 2024 18:00  |  Security  |  In Progress",
+                      fontSize: 12,
+                      marginTop: 8,
+                      isFontRegular: true,
+                      textColor: context.appColors.textDarkGray,
+                    ),
+                  ],
+                ),
+              ),
+
+              //反馈的内容
+              Container(
+                width: double.infinity,
+                margin: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12.5, bottom: 12.5),
+                padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 25),
+                decoration: BoxDecoration(
+                  color: context.appColors.whiteBG,
+                  borderRadius: BorderRadius.circular(6.0), // 圆角
+                  boxShadow: [
+                    BoxShadow(
+                      color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+                      offset: const Offset(0, 3), // 阴影的偏移量
+                      blurRadius: 8.0, // 模糊半径
+                      spreadRadius: 3.0, // 扩散半径
+                    ),
+                  ],
+                ),
+                child: Column(
+                  children: [
+                    MyTextView(
+                      "Why are there no implementation rules andapplication methods for exchanging old houses for new ones in Jiang han District?",
+                      fontSize: 15,
+                      marginBottom: 15,
+                      isFontRegular: true,
+                      textColor: context.appColors.textDarkGray,
+                    ),
+
+                    //九宫格展示
+                    ImageNineGrid(
+                      isSelectEnable: false,
+                      maxImages: 10,
+                      spacing: 10,
+                      aspectRatio: 108 / 80,
+                      initialImages: const [
+                        "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
+                        "https://inews.gtimg.com/om_bt/OE8piEBa-tbqn-wNvWZl8coi4AlzoUD43upEkoAnIkYL8AA/641",
+                        "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
+                        "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
+                      ],
+                      onImagesChanged: (list) {},
+                    ),
+                  ],
+                ),
+              ),
+
+              //回复的数据
+              state.isReplyState ? _buildReplyWidget(context, ref) : _buildWaitingWidget(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _buildReplyWidget(BuildContext context, WidgetRef ref) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Row(
+          mainAxisSize: MainAxisSize.max,
+          mainAxisAlignment: MainAxisAlignment.start,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            MyTextView(
+              S.current.administrator_reply,
+              fontSize: 18,
+              isFontRegular: true,
+              textColor: context.appColors.textBlack,
+            ).expanded(),
+            MyTextView(
+              "20 sep 2024 18:00",
+              fontSize: 12,
+              isFontRegular: true,
+              textColor: context.appColors.textDarkGray,
+            )
+          ],
+        ).marginOnly(left: 12.5, right: 12.5,bottom: 14,top: 2.5),
+
+        //回复的内容
+        Container(
+          width: double.infinity,
+          margin: const EdgeInsets.only(left: 12.5, right: 12.5, bottom: 13.5),
+          padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 25),
+          decoration: BoxDecoration(
+            color: context.appColors.whiteBG,
+            borderRadius: BorderRadius.circular(6.0), // 圆角
+            boxShadow: [
+              BoxShadow(
+                color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+                offset: const Offset(0, 3), // 阴影的偏移量
+                blurRadius: 8.0, // 模糊半径
+                spreadRadius: 3.0, // 扩散半径
+              ),
+            ],
+          ),
+          child: Column(
+            children: [
+              MyTextView(
+                "Although the policy of exchanging old houses for new houses in Jianghan District has been released, the specific implementation details and application methods are not yet clear. According to relevant reports, Jianghan District has issued multiple measures for the development of the real estate market, including promoting the trade in policy, but the specific implementation details and application methods have not vet been announced",
+                fontSize: 15,
+                marginBottom: 15,
+                isFontRegular: true,
+                textColor: context.appColors.textDarkGray,
+              ),
+
+              //九宫格展示
+              ImageNineGrid(
+                isSelectEnable: false,
+                maxImages: 10,
+                spacing: 10,
+                aspectRatio: 108 / 80,
+                initialImages: const [
+                  "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
+                  "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
+                  "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
+                ],
+                onImagesChanged: (list) {},
+              ),
+            ],
+          ),
+        )
+      ],
+    );
+  }
+
+  Widget _buildWaitingWidget(BuildContext context) {
+    return SizedBox(
+      width: double.infinity,
+      child: Column(
+        children: [
+          const SizedBox(height: 40),
+          const MyAssetImage(Assets.mainFeedbackWaitingIcon, width: 38, height: 38),
+          MyTextView(
+            S.current.waiting_for_the_administrator,
+            fontSize: 15,
+            marginTop: 11,
+            marginBottom: 40,
+            isFontRegular: true,
+            textColor: context.appColors.textDarkGray,
+          )
+        ],
+      ),
+    );
+  }
+}

+ 18 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart

@@ -0,0 +1,18 @@
+class FeedbackDetailState{
+
+  //是等待状态还是已完成状态(是否已经回复)
+  bool isReplyState;
+
+  FeedbackDetailState({
+     this.isReplyState = false,
+  });
+
+  FeedbackDetailState copyWith({
+    bool? isReplyState,
+  }) {
+    return FeedbackDetailState(
+      isReplyState: isReplyState ?? this.isReplyState,
+    );
+  }
+
+}

+ 15 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart

@@ -0,0 +1,15 @@
+
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'feedback_detail_state.dart';
+part 'feedback_detail_view_model.g.dart';
+
+@riverpod
+class FeedbackDetailViewModel extends _$FeedbackDetailViewModel {
+
+  @override
+  FeedbackDetailState build(){
+    return FeedbackDetailState();
+  }
+
+}

+ 27 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart

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

+ 4 - 1
packages/cpt_main/lib/modules/feedback/history/feedback_history.dart

@@ -7,6 +7,7 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_history_view_model.dart';
 
@@ -44,7 +45,9 @@ class FeedbackHistoryScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]);
+                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
+                      FeedbackDetailPage.startInstance(context: context);
+                    });
                   },
                   childCount: state.datas.length,
                 ))

+ 1 - 1
packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_history_view_model.dart';
 // **************************************************************************
 
 String _$feedbackHistoryViewModelHash() =>
-    r'5869d2c0a3ce33d7f4a70a08c361142737840a18';
+    r'1be8a480c3593a25a17cd22deeefe9d707f6151a';
 
 /// See also [FeedbackHistoryViewModel].
 @ProviderFor(FeedbackHistoryViewModel)

+ 2 - 1
packages/cpt_main/lib/modules/feedback/item_feedback.dart

@@ -39,6 +39,7 @@ class FeedbackItem extends StatelessWidget {
             children: [
               const MyAssetImage(Assets.mainFeedbackItemIcon, width: 42.5, height: 44),
               Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
 
                   MyTextView(
@@ -56,7 +57,7 @@ class FeedbackItem extends StatelessWidget {
                     isFontRegular: true,
                   ),
                 ],
-              ).expanded(),
+              ).marginOnly(left: 11).expanded(),
             ],
           ),
 

+ 4 - 1
packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart

@@ -7,6 +7,7 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_progress_view_model.dart';
 
@@ -44,7 +45,9 @@ class FeedbackProgressScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]);
+                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
+                      FeedbackDetailPage.startInstance(context: context);
+                    });
                   },
                   childCount: state.datas.length,
                 ))

+ 1 - 1
packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_progress_view_model.dart';
 // **************************************************************************
 
 String _$feedbackProgressViewModelHash() =>
-    r'd9040263f4a23547763ff1f1325a1bff300f77f4';
+    r'0753e433b0a575a262661e6b99030d250b69d0d0';
 
 /// See also [FeedbackProgressViewModel].
 @ProviderFor(FeedbackProgressViewModel)

+ 2 - 1
packages/cpt_main/lib/modules/feedback/send/feedback_send_large.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_main/modules/feedback/create/feedback_create_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';
@@ -39,7 +40,7 @@ class FeedbackSendLarge extends StatelessWidget {
             ),
             MyButton(
               onPressed: () {
-                ToastEngine.show("去填写表单");
+                FeedbackCreatePage.startInstance(context: context);
               },
               text: S.current.create_new_feedback,
               textColor: Colors.white,

+ 3 - 1
packages/cpt_main/lib/modules/feedback/send/feedback_send_small.dart

@@ -8,6 +8,8 @@ import 'package:widgets/my_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../create/feedback_create_page.dart';
+
 class FeedbackSendSmall extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
@@ -36,7 +38,7 @@ class FeedbackSendSmall extends StatelessWidget {
           ),
           MyButton(
             onPressed: () {
-              ToastEngine.show("去填写表单");
+              FeedbackCreatePage.startInstance(context: context);
             },
             text: S.current.create_new_feedback,
             textColor: Colors.white,

+ 9 - 7
packages/cpt_main/lib/modules/home/home_view_model.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_main/modules/home/property_news/home_property_news_page.dart';
 import 'package:cpt_main/modules/notification/notification_page.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -5,6 +6,8 @@ import 'package:router/componentRouter/community_service.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
 
 import 'home_state.dart';
+import 'latest_news/latest_news_page.dart';
+import 'management_guides/management_guides_page.dart';
 
 part 'home_view_model.g.dart';
 
@@ -58,16 +61,15 @@ class HomeViewModel extends _$HomeViewModel {
     ComponentServiceManager().rewardsService.startRewardsPage();
   }
 
-  void gotoLastNewsPage(){
-    ToastEngine.show("去最近新闻的页面");
+  void gotoLastNewsPage() {
+    LatestNewsPage.startInstance();
   }
 
-  void gotoPropertyNewsPage(){
-    ToastEngine.show("去房产新闻的页面");
+  void gotoPropertyNewsPage() {
+    HomePropertyNewsPage.startInstance();
   }
 
-  void gotoManageGuidePage(){
-    ToastEngine.show("去管理员指引的页面");
+  void gotoManageGuidePage() {
+    ManagementGuidesPage.startInstance();
   }
-
 }

+ 1 - 1
packages/cpt_main/lib/modules/home/home_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'home_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$homeViewModelHash() => r'6ec7a8712028daa4d43ace46ea0269981b237187';
+String _$homeViewModelHash() => r'9ad38aa4741b3216454b6652963eb10af930f3d8';
 
 /// See also [HomeViewModel].
 @ProviderFor(HomeViewModel)

+ 55 - 0
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_screen.dart

@@ -0,0 +1,55 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'latest_news_info_view_model.dart';
+
+
+@RoutePage()
+class LatestNewsInfoScreen extends HookConsumerWidget {
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(latestNewsInfoViewModelProvider.notifier);
+    final state = ref.watch(latestNewsInfoViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Container(
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return ListNewsItem(index: index, item: state.datas[index]);
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
+    );
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_state.dart

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

+ 130 - 0
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.dart

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

+ 27 - 0
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.g.dart

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

+ 54 - 0
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_screen.dart

@@ -0,0 +1,54 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'latest_news_internal_view_model.dart';
+
+
+@RoutePage()
+class LatestNewsInternalScreen extends HookConsumerWidget {
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(latestNewsInternalViewModelProvider.notifier);
+    final state = ref.watch(latestNewsInternalViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Container(
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return ListNewsItem(index: index, item: state.datas[index]);
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
+    );
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_state.dart

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

+ 130 - 0
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.dart

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

+ 28 - 0
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.g.dart

@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'latest_news_internal_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$latestNewsInternalViewModelHash() =>
+    r'109c11826358639b41d979660e1528e63a002be8';
+
+/// See also [LatestNewsInternalViewModel].
+@ProviderFor(LatestNewsInternalViewModel)
+final latestNewsInternalViewModelProvider = AutoDisposeNotifierProvider<
+    LatestNewsInternalViewModel, LatestNewsInternalState>.internal(
+  LatestNewsInternalViewModel.new,
+  name: r'latestNewsInternalViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$latestNewsInternalViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$LatestNewsInternalViewModel
+    = AutoDisposeNotifier<LatestNewsInternalState>;
+// 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

+ 152 - 0
packages/cpt_main/lib/modules/home/latest_news/latest_news_page.dart

@@ -0,0 +1,152 @@
+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:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/main_page_router.dart';
+
+@RoutePage()
+class LatestNewsPage extends StatelessWidget {
+  const LatestNewsPage({Key? key}) : super(key: key);
+
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const LatestNewsPageRoute());
+    } else {
+      appRouter.push(const LatestNewsPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        S.current.latest_news,
+        showBackButton: false,
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDark,
+      body: AutoTabsRouter.pageView(
+        routes: const [
+          LatestNewsPropertyPageRoute(),
+          LatestNewsInternalPageRoute(),
+          LatestNewsInfoPageRoute(),
+          LatestNewsPublishPageRoute(),
+        ],
+        builder: (context, child, pageController) {
+          final tabsRouter = AutoTabsRouter.of(context);
+
+          return Column(
+            children: [
+              Container(
+                color: context.appColors.whiteBG,
+                height: 120,
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceAround,
+                  children: [
+                    _buildFeedbackCategory(
+                      context,
+                      Assets.mainLatestProperty,
+                      53.5,
+                      47,
+                      S.current.property,
+                      tabsRouter.activeIndex == 0,
+                    ).onTap(
+                      () {
+                        tabsRouter.setActiveIndex(0);
+                      },
+                    ),
+                    _buildFeedbackCategory(
+                      context,
+                      Assets.mainLatestInternal,
+                      38.5,
+                      45.5,
+                      S.current.internal,
+                      tabsRouter.activeIndex == 1,
+                    ).onTap(
+                      () {
+                        tabsRouter.setActiveIndex(1);
+                      },
+                    ),
+                    _buildFeedbackCategory(
+                      context,
+                      Assets.mainLatestInfo,
+                      45,
+                      47.5,
+                      S.current.info,
+                      tabsRouter.activeIndex == 2,
+                    ).onTap(
+                      () {
+                        tabsRouter.setActiveIndex(2);
+                      },
+                    ),
+                    _buildFeedbackCategory(
+                      context,
+                      Assets.mainLatestPublish,
+                      44,
+                      47,
+                      S.current.publish,
+                      tabsRouter.activeIndex == 3,
+                    ).onTap(
+                          () {
+                        tabsRouter.setActiveIndex(3);
+                      },
+                    ),
+                  ],
+                ),
+              ),
+              Expanded(
+                child: child,
+              ),
+            ],
+          );
+        },
+      ),
+    );
+  }
+
+  //顶部的Tab布局
+  Widget _buildFeedbackCategory(BuildContext context, String iconPath, double iconWidth, double iconHeight, String title, bool isSelected) {
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: <Widget>[
+        Container(
+          width: 70,
+          height: 70,
+          decoration: BoxDecoration(
+            color: context.appColors.lightBlueBg, // 设置圆形背景颜色
+            shape: BoxShape.circle, // 设置为圆形
+            boxShadow: isSelected
+                ? [
+                    BoxShadow(
+                      color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
+                      blurRadius: 5, // 设置模糊半径
+                      spreadRadius: 0.05, // 控制阴影扩散
+                      offset: const Offset(0, 4), // 设置阴影偏移量
+                    ),
+                  ]
+                : [], // 未选中时无阴影,
+          ),
+          child: Center(
+            child: MyAssetImage(iconPath, width: iconWidth, height: iconHeight),
+          ),
+        ),
+        const SizedBox(height: 7),
+        MyTextView(
+          title,
+          fontSize: 15,
+          isFontMedium: true,
+          textColor: isSelected ? context.appColors.tabTextSelectedDefault : context.appColors.tabTextUnSelectedDefault,
+        ),
+      ],
+    );
+  }
+}

+ 54 - 0
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_screen.dart

@@ -0,0 +1,54 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'latest_news_property_view_model.dart';
+
+
+@RoutePage()
+class LatestNewsPropertyScreen extends HookConsumerWidget {
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(latestNewsPropertyViewModelProvider.notifier);
+    final state = ref.watch(latestNewsPropertyViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Container(
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return ListNewsItem(index: index, item: state.datas[index]);
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
+    );
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_state.dart

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

+ 131 - 0
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.dart

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

+ 28 - 0
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.g.dart

@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'latest_news_property_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$latestNewsPropertyViewModelHash() =>
+    r'4c01555638d9c2819e0bd77ffb044a9bf9ff2b1f';
+
+/// See also [LatestNewsPropertyViewModel].
+@ProviderFor(LatestNewsPropertyViewModel)
+final latestNewsPropertyViewModelProvider = AutoDisposeNotifierProvider<
+    LatestNewsPropertyViewModel, LatestNewsPropertyState>.internal(
+  LatestNewsPropertyViewModel.new,
+  name: r'latestNewsPropertyViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$latestNewsPropertyViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$LatestNewsPropertyViewModel
+    = AutoDisposeNotifier<LatestNewsPropertyState>;
+// 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

+ 54 - 0
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_screen.dart

@@ -0,0 +1,54 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'latest_news_publish_view_model.dart';
+
+
+@RoutePage()
+class LatestNewsPublishScreen extends HookConsumerWidget {
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(latestNewsPublishViewModelProvider.notifier);
+    final state = ref.watch(latestNewsPublishViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Container(
+      width: double.infinity,
+      height: double.infinity,
+      child: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        onLoad: viewModel.loadMore,
+        child: LoadStateLayout(
+          state: state.loadingState,
+          errorMessage: state.errorMessage,
+          errorRetry: () {
+            viewModel.retryRequest();
+          },
+          successSliverWidget: [
+            SliverList(
+                delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                    return ListNewsItem(index: index, item: state.datas[index]);
+                  },
+                  childCount: state.datas.length,
+                ))
+          ],
+        ),
+      ).marginOnly(top: 5, bottom: 5),
+    );
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_state.dart

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

+ 130 - 0
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.dart

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

+ 28 - 0
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.g.dart

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

+ 56 - 0
packages/cpt_main/lib/modules/home/management_guides/item_management_guide.dart

@@ -0,0 +1,56 @@
+import 'package:cpt_main/modules/feedback/feedback_page.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+class ManagementGuideItem extends StatelessWidget {
+  final String? iconImage;
+  final String? title;
+
+  ManagementGuideItem({
+    this.iconImage,
+    this.title,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: context.appColors.lightBlueBg,
+        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, // 扩散半径
+          ),
+        ],
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisAlignment: MainAxisAlignment.start,
+        children: [
+          AspectRatio(
+            aspectRatio: 165 / 108, // 设置宽高比例为 165:108
+            child: MyAssetImage(
+              iconImage ?? "-",
+              width: double.infinity,
+              height: double.infinity,
+            ),
+          ),
+          MyTextView(
+            title ?? "-",
+            marginLeft: 9,
+            marginTop: 15,
+            maxLines: 2,
+            fontSize: 15,
+            isFontMedium: true,
+            textColor: context.appColors.tabTextUnSelectedPrimary,
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 84 - 0
packages/cpt_main/lib/modules/home/management_guides/management_guides_page.dart

@@ -0,0 +1,84 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'item_management_guide.dart';
+import 'management_guides_view_model.dart';
+
+@RoutePage()
+class ManagementGuidesPage extends HookConsumerWidget {
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const ManagementGuidesPageRoute());
+    } else {
+      appRouter.push(const ManagementGuidesPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(managementGuidesViewModelProvider.notifier);
+    final state = ref.watch(managementGuidesViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.strata_management_guides, backgroundColor: context.appColors.whiteBG),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Container(
+        width: double.infinity,
+        height: double.infinity,
+        child: EasyRefresh(
+          controller: viewModel.refreshController,
+          onRefresh: viewModel.onRefresh,
+          onLoad: viewModel.loadMore,
+          child: LoadStateLayout(
+            state: state.loadingState,
+            errorMessage: state.errorMessage,
+            errorRetry: () {
+              viewModel.retryRequest();
+            },
+            successSliverWidget: [
+              SliverPadding(
+                padding: const EdgeInsets.symmetric(horizontal: 15.0,vertical: 7), // 设置四周的间距
+                sliver: SliverGrid(
+                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+                    crossAxisCount: 2, // 两列
+                    mainAxisSpacing: 10.0, // 主轴(上下)的间距
+                    crossAxisSpacing: 15.0, // 交叉轴(左右)的间距
+                    childAspectRatio: 165 / 181, // 子组件的宽高比
+                  ),
+                  delegate: SliverChildBuilderDelegate(
+                        (BuildContext context, int index) {
+                      return ManagementGuideItem(
+                        iconImage: state.datas[index].iconImage,
+                        title: state.datas[index].title,
+                      ); // 生成每个网格项
+                    },
+                    childCount: state.datas.length, // 总共的网格项数
+                  ),
+                ),
+              )
+            ],
+          ),
+        ).marginOnly(top: 10, bottom: 5),
+      ),
+    );
+  }
+}

+ 32 - 0
packages/cpt_main/lib/modules/home/management_guides/management_guides_state.dart

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

+ 144 - 0
packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.dart

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

+ 28 - 0
packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.g.dart

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

+ 4 - 0
packages/cpt_main/lib/modules/home/management_guides/test_guide_bean.dart

@@ -0,0 +1,4 @@
+class TestGuideBean{
+  String? iconImage;
+  String? title;
+}

+ 72 - 0
packages/cpt_main/lib/modules/home/property_news/home_property_news_page.dart

@@ -0,0 +1,72 @@
+import 'package:auto_route/auto_route.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'item_list_news.dart';
+import 'home_property_news_view_model.dart';
+
+@RoutePage()
+class HomePropertyNewsPage extends HookConsumerWidget {
+
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const HomePropertyNewsPageRoute());
+    } else {
+      appRouter.push(const HomePropertyNewsPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(homePropertyNewsViewModelProvider.notifier);
+    final state = ref.watch(homePropertyNewsViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.property_news, backgroundColor: context.appColors.whiteBG),
+      backgroundColor: context.appColors.backgroundDark,
+      body: Container(
+        width: double.infinity,
+        height: double.infinity,
+        child: EasyRefresh(
+          controller: viewModel.refreshController,
+          onRefresh: viewModel.onRefresh,
+          onLoad: viewModel.loadMore,
+          child: LoadStateLayout(
+            state: state.loadingState,
+            errorMessage: state.errorMessage,
+            errorRetry: () {
+              viewModel.retryRequest();
+            },
+            successSliverWidget: [
+              SliverList(
+                  delegate: SliverChildBuilderDelegate(
+                (context, index) {
+                  return ListNewsItem(index: index, item: state.datas[index]);
+                },
+                childCount: state.datas.length,
+              ))
+            ],
+          ),
+        ).marginOnly(top: 10, bottom: 5),
+      ),
+    );
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/home/property_news/home_property_news_state.dart

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

+ 130 - 0
packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.dart

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

+ 28 - 0
packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.g.dart

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

+ 68 - 0
packages/cpt_main/lib/modules/home/property_news/item_list_news.dart

@@ -0,0 +1,68 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  首页新闻News 的Item
+class ListNewsItem extends StatelessWidget {
+  final int index;
+  final String item;
+
+  const ListNewsItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      height: 117.5,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteBG,
+        borderRadius: BorderRadius.circular(6.0), // 圆角
+        boxShadow: [
+          BoxShadow(
+            color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+            offset: const Offset(0, 3), // 阴影的偏移量
+            blurRadius: 8.0, // 模糊半径
+            spreadRadius: 3.0, // 扩散半径
+          ),
+        ],
+      ),
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        children: [
+          MyLoadImage(
+            "https://pic.rmb.bdstatic.com/bjh/news/e991d703e32e11c2414ca1298410cc3a8789.jpeg",
+            width: 100,
+            height: 117.5,
+          ).marginOnly(right: 18),
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              MyTextView(
+                "On Monday, the real estate market stopped falling and stabilized, and a devices",
+                marginTop: 12,
+                fontSize: 16,
+                maxLines: 3,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ).expanded(),
+              MyTextView(
+                "Monday 14 0ct 2024",
+                fontSize: 12,
+                marginBottom: 12,
+                marginTop: 12,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+            ],
+          ).expanded(),
+        ],
+      ),
+    );
+  }
+}

+ 210 - 28
packages/cpt_main/lib/modules/me/me_page.dart

@@ -1,41 +1,223 @@
+import 'package:cpt_main/modules/demo_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:cs_resources/theme/theme_config.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
-import 'package:plugin_basic/modules/global_web_page.dart';
-import 'package:plugin_basic/provider/user_config/user_config_service.dart';
-import 'package:router/componentRouter/component_service_manager.dart';
+import 'package:hooks_riverpod/hooks_riverpod.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/setting_item_container.dart';
+
+import 'me_view_model.dart';
 
 @RoutePage()
-class MePage extends StatelessWidget {
+class MePage extends HookConsumerWidget {
   const MePage({Key? key}) : super(key: key);
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(meViewModelProvider.notifier);
+
     return Scaffold(
-      appBar: AppBar(title: Text("Me")),
-      body:Center(
-        child: Column(
-          children: [
-            ElevatedButton(
-              onPressed: () {
-                UserConfigService.getInstance().setUserInfo("李四");
-              },
-              child: const Text('跨页面修改用户信息'),
-            ),
-            ElevatedButton(
-              onPressed: () {
-               ComponentServiceManager().profileService.startEditProfilePage(context: context);
-              },
-              child: const Text('Go to Edit Profile Page'),
-            ),
-            ElevatedButton(
-              onPressed: () {
-               GlobalWebPage.startInstance(context: context, title: "baidu", url: "https://www.baidu.com");
-              },
-              child: const Text('Go to Global Web Page'),
-            ),
-          ],
+      appBar: MyAppBar.appBar(
+        context,
+        "",
+        showBackButton: false,
+        backgroundColor: context.appColors.btnBgDefault,
+        systemUiOverlayStyle: 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(
+                  "265",
+                  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(
+                  "2",
+                  textColor: context.appColors.textPrimary,
+                  fontSize: 20,
+                  isFontMedium: true,
+                ),
+              ).onTap(viewModel.gotoMyHouseholdPage),
+
+              //房产
+              SettingItemContainer(
+                title: S.current.estate,
+                iconPath: Assets.mainMeEstateIcon,
+                isShowMoreIcon: true,
+                rightWidget: MyTextView(
+                  "2",
+                  textColor: context.appColors.textPrimary,
+                  fontSize: 20,
+                  isFontMedium: true,
+                ),
+              ).onTap(viewModel.gotoMyEstatePage),
+
+              //设置
+              SettingItemContainer(
+                title: S.current.settings,
+                iconPath: Assets.mainMeSettingIcon,
+                isShowMoreIcon: true,
+              ).onTap(viewModel.gotoSettingPage),
+
+            ],
+          ),
         ),
       ),
     );
   }
+
+  //编辑顶部的关注与粉丝数量
+  Widget _buildFollower(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(meViewModelProvider.notifier);
+    return Container(
+      color: context.appColors.whiteSecondBG,
+      width: double.infinity,
+      height: 50,
+      child: Row(
+        children: [
+          //关注
+          Row(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.center,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                S.current.following,
+                isFontBold: true,
+                fontSize: 16,
+                textColor: context.appColors.textBlack,
+              ),
+              MyTextView(
+                "(26)",
+                isFontBold: true,
+                fontSize: 16,
+                textColor: context.appColors.textPrimary,
+              ),
+            ],
+          ).onTap(viewModel.gotoFollowingPage).expanded(),
+
+          Container(
+            width: 0.5,
+            height: 50,
+            color: context.appColors.dividerDefault,
+          ),
+          //粉丝
+          Row(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.center,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                S.current.followers,
+                isFontBold: true,
+                fontSize: 16,
+                textColor: context.appColors.textBlack,
+              ),
+              MyTextView(
+                "(12)",
+                isFontBold: true,
+                fontSize: 16,
+                textColor: context.appColors.textPrimary,
+              ),
+            ],
+          ).onTap(viewModel.gotoFollowerPage).expanded(),
+        ],
+      ),
+    );
+  }
+
+  // 编辑顶部的个人信息
+  Widget _buildTopProfile(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(meViewModelProvider.notifier);
+    return Container(
+      color: context.appColors.btnBgDefault,
+      width: double.infinity,
+      padding: const EdgeInsets.only(left: 26, right: 20, top: 5),
+      height: 120,
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          MyLoadImage(
+            "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+            width: 80,
+            height: 80,
+            isCircle: true,
+          ),
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Row(
+                children: [
+                  MyTextView(
+                    "Wu Bing Bing",
+                    textColor: Colors.white,
+                    fontSize: 18,
+                    isFontMedium: true,
+                  ).expanded(),
+                  const MyAssetImage(
+                    Assets.mainMeEditIcon,
+                    width: 20.5,
+                    height: 20,
+                  ).onTap(viewModel.gotoEditProfilePage, padding: 5),
+                ],
+              ),
+
+              //电话
+              MyTextView(
+                "+86 12345678901",
+                textColor: Colors.white,
+                fontSize: 15,
+                isFontRegular: true,
+              ),
+
+              //住宅
+              MyTextView(
+                "Owner135 #08-29",
+                marginTop: 12,
+                textColor: Colors.white,
+                fontSize: 15,
+                isFontRegular: true,
+              ),
+            ],
+          ).marginOnly(left: 11).expanded(),
+        ],
+      ),
+    );
+  }
 }

+ 46 - 0
packages/cpt_main/lib/modules/me/me_view_model.dart

@@ -0,0 +1,46 @@
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
+
+part 'me_view_model.g.dart';
+
+@riverpod
+class MeViewModel extends _$MeViewModel {
+  @override
+  void build() {}
+
+  //去我的房产页面
+  void gotoMyEstatePage() {
+    ComponentServiceManager().profileService.startMyEstatePage();
+  }
+
+  //去我的家庭成员页面
+  void gotoMyHouseholdPage() {
+    ComponentServiceManager().profileService.startMyHouseHoldPage();
+  }
+
+  //去我的发布页面
+  void gotoMyPostPage() {
+    ToastEngine.show("去我的发布页面");
+  }
+
+  //去设置页面
+  void gotoSettingPage() {
+    ComponentServiceManager().profileService.startSettingPage();
+  }
+
+  //我的关注Tab
+  void gotoFollowingPage() {
+    ToastEngine.show("我的关注Tab");
+  }
+
+  //我的粉丝Tab
+  void gotoFollowerPage() {
+    ToastEngine.show("我的粉丝Tab");
+  }
+
+  //编辑附加信息
+  void gotoEditProfilePage() {
+    ComponentServiceManager().profileService.startEditProfilePage();
+  }
+}

+ 25 - 0
packages/cpt_main/lib/modules/me/me_view_model.g.dart

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

+ 99 - 0
packages/cpt_main/lib/modules/notification/item_notification.dart

@@ -0,0 +1,99 @@
+import 'package:cpt_main/modules/demo_page.dart';
+import 'package:cpt_main/modules/notification/notification_group_data.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+class NotificationItem extends StatelessWidget {
+  final String item;
+  final int index;
+
+  const NotificationItem({
+    required this.item,
+    required this.index,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      color: context.appColors.whiteBG,
+      padding: const EdgeInsets.only(left: 11, right: 15, top: 10.5),
+      child: Column(
+        children: [
+          Row(
+            children: [
+              const MyAssetImage(Assets.mainNotificationItemIcon, width: 42.5, height: 42.5).marginOnly(right: 16),
+              Column(
+                children: [
+                  //标题
+                  Row(
+                    crossAxisAlignment: CrossAxisAlignment.center,
+                    children: [
+                      //未读的小圆点
+                      Container(
+                        width: 6,
+                        height: 6,
+                        margin: const EdgeInsets.only(right: 8.5),
+                        decoration: BoxDecoration(
+                          shape: BoxShape.circle,
+                          color: context.appColors.tabBgSelectedPrimary,
+                        ),
+                      ),
+
+                      //消息标题
+                      MyTextView(
+                        "NEW ANNOUNCEMENT",
+                        fontSize: 16,
+                        isFontBold: true,
+                        textColor: context.appColors.textBlack,
+                        maxLines: 2,
+                      ).expanded(),
+
+                      //消息时间
+                      MyTextView(
+                        "10:19 AM",
+                        fontSize: 13,
+                        isFontRegular: true,
+                        textColor: context.appColors.textLightPurple,
+                      ),
+                    ],
+                  ),
+
+                  //内容
+                  Row(
+                    children: [
+                      //文本内容
+                      MyTextView(
+                        "Standard operating procedure for replacement vehicles andover night parking vehicles.",
+                        fontSize: 15,
+                        marginRight: 15,
+                        isFontRegular: true,
+                        textColor: context.appColors.textBlack,
+                      ).expanded(),
+
+                      //图片
+                      MyLoadImage(
+                        "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                        width: 87.5,
+                        height: 60.5,
+                      ),
+                    ],
+                  ).marginOnly(top: 9),
+                ],
+              ).expanded(),
+            ],
+          ),
+          const SizedBox(height: 17.5),
+          Divider(
+            height: 0.5,
+            color: context.appColors.backgroundDark,
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 26 - 0
packages/cpt_main/lib/modules/notification/item_notification_header.dart

@@ -0,0 +1,26 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/my_text_view.dart';
+
+class NotificationItemHeader extends StatelessWidget {
+  String? groupId;
+
+  NotificationItemHeader(this.groupId);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      color: context.appColors.backgroundDark,
+      padding: const EdgeInsets.symmetric(horizontal: 14),
+      child: MyTextView(
+        groupId ?? "-",
+        fontSize: 14,
+        paddingTop: 8,
+        paddingBottom: 8,
+        isFontMedium: true,
+        textColor: context.appColors.textBlack,
+      ),
+    );
+  }
+}

+ 6 - 0
packages/cpt_main/lib/modules/notification/notification_group_data.dart

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

+ 78 - 7
packages/cpt_main/lib/modules/notification/notification_page.dart

@@ -1,11 +1,23 @@
+import 'package:cpt_main/modules/notification/item_notification_header.dart';
 import 'package:cpt_main/router/page/main_page_router.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
-@RoutePage()
-class NotificationPage extends StatelessWidget {
+import 'item_notification.dart';
+import 'notification_view_model.dart';
 
+@RoutePage()
+class NotificationPage extends HookConsumerWidget {
   const NotificationPage({Key? key}) : super(key: key);
 
   static void startInstance({BuildContext? context}) {
@@ -17,12 +29,71 @@ class NotificationPage extends StatelessWidget {
   }
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.read(notificationViewModelProvider.notifier);
+    final state = ref.watch(notificationViewModelProvider);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchList());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Scaffold(
-      appBar: AppBar(title: Text("NotificationPage")),
-      body: Center(
-        child: Text("Notification Page"),
+      appBar: MyAppBar.appBar(context, S.current.notification,
+          backgroundColor: context.appColors.whiteBG,
+          actions: [
+            Center(
+                child: MyTextView(
+              S.current.mark_all,
+              fontSize: 16,
+              textColor: context.appColors.textPrimary,
+              onClick: viewModel.markAll,
+              isFontRegular: true,
+              marginRight: 15,
+            )),
+          ],
+          showBottomDivider: false),
+      backgroundColor: context.appColors.whiteBG,
+      body: SizedBox(
+        width: double.infinity,
+        height: double.infinity,
+        child: EasyRefresh(
+          controller: viewModel.refreshController,
+          onRefresh: viewModel.onRefresh,
+          onLoad: viewModel.loadMore,
+          child: LoadStateLayout(
+            state: state.loadingState,
+            errorMessage: state.errorMessage,
+            errorRetry: () {
+              viewModel.retryRequest();
+            },
+            successSliverWidget: [
+              SliverList(
+                  delegate: SliverChildBuilderDelegate(
+                (context, index) {
+                  return StickyHeader(
+                    header: NotificationItemHeader(state.datas[index].groupId),
+                    content: Column(
+                      children: _buildGroup(state.datas[index].groupDatas!, index),
+                    ),
+                  );
+                },
+                childCount: state.datas.length,
+              ))
+            ],
+          ),
+        ),
       ),
     );
   }
-}
+
+  //当前组内的子数据
+  _buildGroup(List<String> list, int index) {
+    return list.map((item) {
+      return NotificationItem(item: item, index: index);
+    }).toList();
+  }
+}

+ 31 - 0
packages/cpt_main/lib/modules/notification/notification_state.dart

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

+ 160 - 0
packages/cpt_main/lib/modules/notification/notification_view_model.dart

@@ -0,0 +1,160 @@
+import 'package:cpt_main/modules/notification/notification_group_data.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'notification_state.dart';
+
+part 'notification_view_model.g.dart';
+
+@riverpod
+class NotificationViewModel extends _$NotificationViewModel {
+  @override
+  NotificationState build() {
+    return NotificationState(datas: []);
+  }
+
+  var _curPage = 1; //请求参数当前的页面
+  var _needShowPlaceholder = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
+  );
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchList();
+  }
+
+  /// 获取服务器数据
+  Future fetchList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    // 获取 Applied 列表
+    // var listResult = await _jobRepository.fetchJobAppliedList(
+    //   state.jobId,
+    //   state.selectedStatusId,
+    //   state.keyword,
+    //   curPage: _curPage,
+    //   cancelToken: cancelToken,
+    // );
+    //
+    // // 处理数据
+    // if (listResult.isSuccess) {
+    //   handleList(listResult.data?.rows);
+    // } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    // }
+
+    await Future.delayed(const Duration(milliseconds: 1500));
+
+    List<NotificationGroupData> list = [];
+    if (_curPage > 1) {
+
+      //这里只加载一页吧
+    } else {
+
+      list.add(NotificationGroupData()
+        ..groupId = "Toady"
+        ..groupDatas = ["1", "2", "3", "4"]);
+
+      list.add(NotificationGroupData()
+        ..groupId = "Friday 11 oct 2024"
+        ..groupDatas = ["1", "2", "3"]);
+
+      list.add(NotificationGroupData()
+        ..groupId = "Thursday 10 oct 2024"
+        ..groupDatas = ["1", "2"]);
+
+      list.add(NotificationGroupData()
+        ..groupId = "Wednesday 9 oct 2024"
+        ..groupDatas = ["1"]);
+
+    }
+
+
+    if (_curPage == 1) {
+      //刷新的方式
+      state = state.copyWith(datas: list);
+      refreshController.finishRefresh();
+
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      //加载更多
+      final allList = state.datas;
+      allList.addAll(list);
+      state.datas.addAll(list);
+
+      // refreshController.finishLoad();
+      refreshController.finishLoad(IndicatorResult.noMore);
+
+      state = state.copyWith(datas: allList);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+// 处理数据与展示的逻辑
+// void handleList(List<JobAppliedListSGRows>? list) {
+//   if (list != null && list.isNotEmpty) {
+//     //有数据,判断是刷新还是加载更多的数据
+//     if (_curPage == 1) {
+//       //刷新的方式
+//       state.datas.clear();
+//       state.datas.addAll(list);
+//       refreshController.finishRefresh();
+//
+//       //更新展示的状态
+//       changeLoadingState(LoadState.State_Success);
+//     } else {
+//       //加载更多
+//       state.datas.addAll(list);
+//       refreshController.finishLoad();
+//       update();
+//     }
+//   } else {
+//     if (_curPage == 1) {
+//       //展示无数据的布局
+//       state.datas.clear();
+//       changeLoadingState(LoadState.State_Empty);
+//       refreshController.finishRefresh();
+//     } else {
+//       //展示加载完成,没有更多数据了
+//       refreshController.finishLoad(IndicatorResult.noMore);
+//     }
+//   }
+// }
+
+  /// 点击标记全部
+  void markAll() {
+    ToastEngine.show("点击标记全部");
+  }
+
+}

+ 27 - 0
packages/cpt_main/lib/modules/notification/notification_view_model.g.dart

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

+ 3 - 1
packages/cpt_main/lib/modules/visitor/now/visitor_now_large.dart

@@ -9,6 +9,8 @@ import 'package:widgets/my_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../register/visitor_register_page.dart';
+
 class VisitorNowLarge extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
@@ -33,7 +35,7 @@ class VisitorNowLarge extends StatelessWidget {
             ),
             MyButton(
               onPressed: () {
-                ToastEngine.show("去填写表单");
+                VisitorRegisterPage.startInstance(context: context);
               },
               text: S.current.visitor_registration,
               textColor: Colors.white,

+ 3 - 1
packages/cpt_main/lib/modules/visitor/now/visitor_now_small.dart

@@ -9,6 +9,8 @@ import 'package:widgets/my_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../register/visitor_register_page.dart';
+
 class VisitorNowSmall extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
@@ -30,7 +32,7 @@ class VisitorNowSmall extends StatelessWidget {
           ),
           MyButton(
             onPressed: (){
-              ToastEngine.show("去填写表单");
+              VisitorRegisterPage.startInstance(context: context);
             },
             text: S.current.visitor_registration,
             textColor: Colors.white,

+ 296 - 0
packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart

@@ -0,0 +1,296 @@
+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:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_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_view.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/picker_container.dart';
+
+import '../../../router/page/main_page_router.dart';
+import 'visitor_register_state.dart';
+import 'visitor_register_view_model.dart';
+
+@RoutePage()
+class VisitorRegisterPage extends HookConsumerWidget {
+  const VisitorRegisterPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const VisitorRegisterPageRoute());
+    } else {
+      appRouter.push(const VisitorRegisterPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(visitorRegisterViewModelProvider.notifier);
+    final state = ref.watch(visitorRegisterViewModelProvider);
+    final noteCount = useState(0);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.visitor_registration),
+      backgroundColor: context.appColors.whiteBG,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 15),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //全名
+              FormRequireText(
+                text: S.current.full_name,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                marginTop: 16,
+                "full_name",
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                errorText: state.fullNameErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['phone']!['focusNode']);
+                },
+              ),
+
+              //移动电话
+              FormRequireText(
+                text: S.current.mobile_phone,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                "phone",
+                marginTop: 16,
+                textInputType: TextInputType.phone,
+                textInputAction: TextInputAction.next,
+                errorText: state.phoneErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['nric']!['focusNode']);
+                },
+              ),
+
+              // 身份证
+              FormRequireText(
+                text: S.current.nric_fin,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                "nric",
+                marginTop: 15,
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                errorText: state.nricErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['plate_number']!['focusNode']);
+                },
+              ),
+
+              // 车牌号
+              MyTextView(
+                S.current.license_plate_number,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                "plate_number",
+                marginTop: 15,
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['access_date']!['focusNode']);
+                },
+              ),
+
+              // 通行时间
+              MyTextView(
+                S.current.access_date,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+              // 选择器
+              PickerContainer(
+                content: state.accessDate == null ? "" : DateTimeUtils.formatDate(state.accessDate, format: 'dd MMM yyyy'),
+                margin: const EdgeInsets.only(top: 16),
+                rightWidget: const MyAssetImage(Assets.mainVisitorRegisterDate, width: 21, height: 20),
+                onClick: viewModel.pickAccessDate,
+              ),
+
+              // 备注
+              MyTextView(
+                S.current.notes,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+              //大文本框
+              IgnoreKeyboardDismiss(
+                child: Container(
+                  height: 177,
+                  margin: const EdgeInsets.only(top: 16),
+                  padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                  decoration: BoxDecoration(
+                    color: context.appColors.authFiledBG,
+                    borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  ),
+                  child: Stack(
+                    children: [
+                      TextField(
+                        cursorColor: context.appColors.authFiledText,
+                        cursorWidth: 1.5,
+                        autofocus: false,
+                        enabled: true,
+                        focusNode: state.formData["note"]!['focusNode'],
+                        controller: state.formData["note"]!['controller'],
+                        decoration: InputDecoration(
+                          isDense: true,
+                          isCollapsed: true,
+                          border: InputBorder.none,
+                          hintText: state.formData["note"]!['hintText'],
+                          hintStyle: TextStyle(
+                            color: context.appColors.authFiledHint,
+                            fontSize: 16.0,
+                            fontWeight: FontWeight.w500,
+                          ),
+                        ),
+                        style: TextStyle(
+                          color: context.appColors.authFiledText,
+                          fontSize: 16.0,
+                          fontWeight: FontWeight.w500,
+                        ),
+                        textInputAction: TextInputAction.done,
+                        onSubmitted: (value) {
+                          FocusScope.of(context).unfocus();
+                          viewModel.submitVisitorRegister();
+                        },
+                        maxLines: null,
+                        expands: true,
+                        onChanged: (text) {
+                          // 当文本改变时,更新字符数量
+                          noteCount.value = text.length;
+                        },
+                      ),
+                      Positioned(
+                        bottom: 0.0,
+                        right: 0.0,
+                        child: Text(
+                          S.current.characters(noteCount.value),
+                          style: TextStyle(
+                            color: context.appColors.textBlack,
+                            fontSize: 15.0,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+
+              MyButton(
+                onPressed: viewModel.submitVisitorRegister,
+                text: S.current.submit,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 25, bottom: 25),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    VisitorRegisterState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    bool enable = true,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        enabled: enable,
+        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,
+      ),
+    );
+  }
+}

+ 72 - 0
packages/cpt_main/lib/modules/visitor/register/visitor_register_state.dart

@@ -0,0 +1,72 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class VisitorRegisterState {
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  //表单的错误信息展示
+  String? fullNameErrorText;
+  String? phoneErrorText;
+  String? nricErrorText;
+
+  DateTime? accessDate; //通行时间
+
+  // ===================================  Begin  ↓  ===================================
+
+  VisitorRegisterState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.fullNameErrorText,
+    this.phoneErrorText,
+    this.nricErrorText,
+    this.accessDate,
+  }) : formData = formData ??
+            {
+              'full_name': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'phone': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'nric': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'plate_number': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'note': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'hintText': S.current.type_here,
+                'obsecure': false,
+              },
+            };
+
+  VisitorRegisterState copyWith({
+    String? fullNameErrorText,
+    String? phoneErrorText,
+    String? nricErrorText,
+    DateTime? accessDate,
+  }) {
+    return VisitorRegisterState(
+      formData: this.formData,
+      fullNameErrorText: fullNameErrorText,
+      phoneErrorText: phoneErrorText,
+      nricErrorText: nricErrorText,
+      accessDate: accessDate ?? this.accessDate,
+    );
+  }
+}

+ 137 - 0
packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart

@@ -0,0 +1,137 @@
+
+import 'package:cpt_main/modules/main/main_page.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/picker/date_picker_util.dart';
+
+import 'visitor_register_state.dart';
+part 'visitor_register_view_model.g.dart';
+
+@riverpod
+class VisitorRegisterViewModel extends _$VisitorRegisterViewModel {
+
+  @override
+  VisitorRegisterState build(){
+    final state = VisitorRegisterState();
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+    return state;
+  }
+
+  //提交表单
+  void submitVisitorRegister() {
+    state = state.copyWith(
+      fullNameErrorText: null,
+      phoneErrorText: null,
+      nricErrorText: null,
+    );
+
+    final FocusNode fullNameFocusNode = state.formData['full_name']!['focusNode'];
+    final FocusNode phoneFocusNode = state.formData['phone']!['focusNode'];
+    final FocusNode nricFocusNode = state.formData['nric']!['focusNode'];
+    final FocusNode plateNumberFocusNode = state.formData['plate_number']!['focusNode'];
+    final FocusNode noteFocusNode = state.formData['note']!['focusNode'];
+
+    fullNameFocusNode.unfocus();
+    phoneFocusNode.unfocus();
+    nricFocusNode.unfocus();
+    plateNumberFocusNode.unfocus();
+    noteFocusNode.unfocus();
+
+    final TextEditingController fullNameController = state.formData['full_name']!['controller'];
+    final TextEditingController phoneController = state.formData['phone']!['controller'];
+    final TextEditingController nricController = state.formData['nric']!['controller'];
+    final TextEditingController plateNumberController = state.formData['plate_number']!['controller'];
+    final TextEditingController noteController = state.formData['note']!['controller'];
+
+    final fullName = fullNameController.text;
+    final phone = phoneController.text;
+    final nric = nricController.text;
+    final plateNumber = plateNumberController.text;
+    final note = noteController.text;
+    final accessDate = state.accessDate == null ?  null : DateTimeUtils.formatDate(state.accessDate!,format: 'yyyy-MM-dd');
+
+    Log.d('当前待提交的 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
+
+    if (Utils.isEmpty(fullName)) {
+      state = state.copyWith(fullNameErrorText: "Full Name cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(phone)) {
+      state = state.copyWith(phoneErrorText: "Mobile Number cannot be empty!");
+      return;
+    }
+
+    if (Utils.isEmpty(nric)) {
+      state = state.copyWith(nricErrorText: "NRIC/FIN cannot be empty!");
+      return;
+    }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
+
+    //去首页
+    MainPage.startInstance();
+  }
+
+  //选择通行时间
+  void pickAccessDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: state.accessDate ?? DateTime.now(),
+      mode: CupertinoDatePickerMode.date,
+      onDateTimeChanged: (date) {
+       state = state.copyWith(accessDate: date);
+      },
+      title: S.current.access_date,
+    );
+  }
+
+  //初始化监听
+  void initListener(VisitorRegisterState initState) {
+    final FocusNode fullNameFocusNode = initState.formData['full_name']!['focusNode'];
+    final FocusNode phoneFocusNode = initState.formData['phone']!['focusNode'];
+    final FocusNode nricFocusNode = initState.formData['nric']!['focusNode'];
+
+    fullNameFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (fullNameFocusNode.hasFocus) {
+        state = state.copyWith(fullNameErrorText: null);
+      }
+    });
+
+    phoneFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (phoneFocusNode.hasFocus) {
+        state = state.copyWith(phoneErrorText: null);
+      }
+    });
+
+    nricFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (nricFocusNode.hasFocus) {
+        state = state.copyWith(nricErrorText: null);
+      }
+    });
+  }
+
+  //销毁资源
+  void onDispose(VisitorRegisterState initState) {
+    final FocusNode fullNameFocusNode = initState.formData['full_name']!['focusNode'];
+    final FocusNode phoneFocusNode = initState.formData['phone']!['focusNode'];
+    final FocusNode nricFocusNode = initState.formData['nric']!['focusNode'];
+    fullNameFocusNode.dispose();
+    phoneFocusNode.dispose();
+    nricFocusNode.dispose();
+
+    Log.d("VisitorRegisterViewModel 销毁 onDispose");
+  }
+
+}

+ 27 - 0
packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.g.dart

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

+ 28 - 0
packages/cpt_main/lib/router/page/main_page_router.dart

@@ -15,6 +15,17 @@ import '../../modules/visitor/visitor_page.dart';
 import '../../modules/visitor/now/visitor_now.dart';
 import '../../modules/visitor/active/visitor_active.dart';
 import '../../modules/visitor/history/visitor_history.dart';
+import '../../modules/home/property_news/home_property_news_page.dart';
+import '../../modules/home/latest_news/info/latest_news_info_screen.dart';
+import '../../modules/home/latest_news/internal/latest_news_internal_screen.dart';
+import '../../modules/home/latest_news/property/latest_news_property_screen.dart';
+import '../../modules/home/latest_news/publish/latest_news_publish_screen.dart';
+import '../../modules/home/latest_news/latest_news_page.dart';
+import '../../modules/home/management_guides/management_guides_page.dart';
+import '../../modules/visitor/register/visitor_register_page.dart';
+import '../../modules/feedback/create/feedback_create_page.dart';
+import '../../modules/feedback/detail/feedback_detail_page.dart';
+import '../../modules/feedback/create_success/feedback_create_success_page.dart';
 
 part 'main_page_router.gr.dart';
 
@@ -53,5 +64,22 @@ class MainPageRouter extends _$MainPageRouter {
           ],
         ),
         CustomRoute(page: NotificationPageRoute.page, path: RouterPath.notification, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: HomePropertyNewsPageRoute.page, path: RouterPath.homePropertyNews, transitionsBuilder: applySlideTransition),
+        CustomRoute(
+          page: LatestNewsPageRoute.page,
+          path: RouterPath.homeLatestNews,
+          transitionsBuilder: applySlideTransition,
+          children: [
+            AutoRoute(page: LatestNewsPropertyPageRoute.page, path: 'property'),
+            AutoRoute(page: LatestNewsInternalPageRoute.page, path: 'internal'),
+            AutoRoute(page: LatestNewsInfoPageRoute.page, path: 'info'),
+            AutoRoute(page: LatestNewsPublishPageRoute.page, path: 'publish'),
+          ],
+        ),
+        CustomRoute(page: ManagementGuidesPageRoute.page, path: RouterPath.homeManagementGuides, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: VisitorRegisterPageRoute.page, path: RouterPath.visitorRegister, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackCreatePageRoute.page, path: RouterPath.feedbackCreate, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackCreateSuccessPageRoute.page, path: RouterPath.feedbackCreateSuccess, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackDetailPageRoute.page, path: RouterPath.feedbackDetail, transitionsBuilder: applySlideTransition),
       ];
 }

+ 220 - 0
packages/cpt_main/lib/router/page/main_page_router.gr.dart

@@ -15,6 +15,24 @@ abstract class _$MainPageRouter extends RootStackRouter {
 
   @override
   final Map<String, PageFactory> pagesMap = {
+    FeedbackCreatePageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackCreatePage(),
+      );
+    },
+    FeedbackCreateSuccessPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackCreateSuccessPage(),
+      );
+    },
+    FeedbackDetailPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackDetailPage(),
+      );
+    },
     FeedbackHistoryPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -45,12 +63,54 @@ abstract class _$MainPageRouter extends RootStackRouter {
         child: const HomePage(),
       );
     },
+    HomePropertyNewsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: HomePropertyNewsPage(),
+      );
+    },
+    LatestNewsInfoPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: LatestNewsInfoScreen(),
+      );
+    },
+    LatestNewsInternalPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: LatestNewsInternalScreen(),
+      );
+    },
+    LatestNewsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const LatestNewsPage(),
+      );
+    },
+    LatestNewsPropertyPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: LatestNewsPropertyScreen(),
+      );
+    },
+    LatestNewsPublishPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: LatestNewsPublishScreen(),
+      );
+    },
     MainPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const MainPage(),
       );
     },
+    ManagementGuidesPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: ManagementGuidesPage(),
+      );
+    },
     MePageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -87,10 +147,58 @@ abstract class _$MainPageRouter extends RootStackRouter {
         child: const VisitorPage(),
       );
     },
+    VisitorRegisterPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const VisitorRegisterPage(),
+      );
+    },
   };
 }
 
 /// generated route for
+/// [FeedbackCreatePage]
+class FeedbackCreatePageRoute extends PageRouteInfo<void> {
+  const FeedbackCreatePageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackCreatePageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackCreatePageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [FeedbackCreateSuccessPage]
+class FeedbackCreateSuccessPageRoute extends PageRouteInfo<void> {
+  const FeedbackCreateSuccessPageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackCreateSuccessPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackCreateSuccessPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [FeedbackDetailPage]
+class FeedbackDetailPageRoute extends PageRouteInfo<void> {
+  const FeedbackDetailPageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackDetailPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackDetailPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [FeedbackHistoryScreen]
 class FeedbackHistoryPageRoute extends PageRouteInfo<void> {
   const FeedbackHistoryPageRoute({List<PageRouteInfo>? children})
@@ -161,6 +269,90 @@ class HomePageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [HomePropertyNewsPage]
+class HomePropertyNewsPageRoute extends PageRouteInfo<void> {
+  const HomePropertyNewsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          HomePropertyNewsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'HomePropertyNewsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [LatestNewsInfoScreen]
+class LatestNewsInfoPageRoute extends PageRouteInfo<void> {
+  const LatestNewsInfoPageRoute({List<PageRouteInfo>? children})
+      : super(
+          LatestNewsInfoPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'LatestNewsInfoPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [LatestNewsInternalScreen]
+class LatestNewsInternalPageRoute extends PageRouteInfo<void> {
+  const LatestNewsInternalPageRoute({List<PageRouteInfo>? children})
+      : super(
+          LatestNewsInternalPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'LatestNewsInternalPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [LatestNewsPage]
+class LatestNewsPageRoute extends PageRouteInfo<void> {
+  const LatestNewsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          LatestNewsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'LatestNewsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [LatestNewsPropertyScreen]
+class LatestNewsPropertyPageRoute extends PageRouteInfo<void> {
+  const LatestNewsPropertyPageRoute({List<PageRouteInfo>? children})
+      : super(
+          LatestNewsPropertyPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'LatestNewsPropertyPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [LatestNewsPublishScreen]
+class LatestNewsPublishPageRoute extends PageRouteInfo<void> {
+  const LatestNewsPublishPageRoute({List<PageRouteInfo>? children})
+      : super(
+          LatestNewsPublishPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'LatestNewsPublishPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [MainPage]
 class MainPageRoute extends PageRouteInfo<void> {
   const MainPageRoute({List<PageRouteInfo>? children})
@@ -175,6 +367,20 @@ class MainPageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [ManagementGuidesPage]
+class ManagementGuidesPageRoute extends PageRouteInfo<void> {
+  const ManagementGuidesPageRoute({List<PageRouteInfo>? children})
+      : super(
+          ManagementGuidesPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'ManagementGuidesPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [MePage]
 class MePageRoute extends PageRouteInfo<void> {
   const MePageRoute({List<PageRouteInfo>? children})
@@ -257,3 +463,17 @@ class VisitorPageRoute extends PageRouteInfo<void> {
 
   static const PageInfo<void> page = PageInfo<void>(name);
 }
+
+/// generated route for
+/// [VisitorRegisterPage]
+class VisitorRegisterPageRoute extends PageRouteInfo<void> {
+  const VisitorRegisterPageRoute({List<PageRouteInfo>? children})
+      : super(
+          VisitorRegisterPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'VisitorRegisterPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}

+ 126 - 0
packages/cpt_notice_board/lib/modules/announ/page/announ_page.dart

@@ -0,0 +1,126 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_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/notice_board_page_router.dart';
+import '../vm/announ_vm.dart';
+
+@RoutePage()
+class AnnounPage extends HookConsumerWidget {
+  const AnnounPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const AnnounPageRoute());
+    } else {
+      appRouter.push(const AnnounPageRoute());
+    }
+  }
+
+  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), // 设置字体大小
+      ),
+    );
+  }
+  Widget _buildItemRightSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.green,
+      child: Text(
+        item['price'],
+        style: const TextStyle(
+            fontSize: 14.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w400), // 设置字体大小
+      ),
+    );
+  }
+
+  // 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: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 100,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                 _buildItemLeftSection(context, ref, item, _vm).marginOnly(bottom: 5),
+                _buildItemRightSection(context, ref, item, _vm),
+              ],
+            ).paddingOnly(left: 20,right: 20),
+          ).constrained(
+            minHeight: 117.5,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item['title']);
+      }),
+    ).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(announVmProvider.notifier);
+
+    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)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/announ/page/announ_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+AnnounState announStateFromJson(String str) => AnnounState.fromJson(json.decode(str));
+
+String announStateToJson(AnnounState data) => json.encode(data.toJson());
+
+class AnnounState {
+  AnnounState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory AnnounState.fromJson(Map<dynamic, dynamic> json) => AnnounState(
+    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,
+  };
+
+  AnnounState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return AnnounState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/announ/repository/announ_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 '../page/announ_state.dart';
+part 'announ_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+AnnounRepository announRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return AnnounRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class AnnounRepository {
+  DioEngine dioEngine;
+
+  AnnounRepository({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 = AnnounState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<AnnounState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.g.dart

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

+ 112 - 0
packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.dart

@@ -0,0 +1,112 @@
+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 '../page/announ_state.dart';
+import '../repository/announ_repository.dart';
+part 'announ_vm.g.dart';
+
+@riverpod
+class AnnounVm extends _$AnnounVm {
+  late AnnounRepository announRepository;
+  AnnounState initState() {
+    return AnnounState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title": "Standard Operating procedure For Replacement V...",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 2,
+          "title": "Removal Of Items In Dry Risers",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 3,
+          "title": "Fire Safety Awareness And Guidelines",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 4,
+          "title": "Bicycle Tagging Exercise",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  AnnounState build() {
+    // 引入数据仓库
+    announRepository = ref.read(announRepositoryProvider);
+    // 初始化状态
+    AnnounState 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 announRepository.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();
+  }
+}

+ 26 - 0
packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.g.dart

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

+ 148 - 0
packages/cpt_notice_board/lib/modules/documents/page/documents_page.dart

@@ -0,0 +1,148 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_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/notice_board_page_router.dart';
+import '../vm/documents_vm.dart';
+
+@RoutePage()
+class DocumentsPage extends HookConsumerWidget {
+  const DocumentsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const DocumentsPageRoute());
+    } else {
+      appRouter.push(const DocumentsPageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.blue,
+      child: Text(
+        item['title'],
+        maxLines: 1, // 设置最大行数为2
+        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+        style: const TextStyle(
+            fontSize: 16.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w700), // 设置字体大小
+      ),
+    ).marginOnly(right: 17.5);
+  }
+
+  Widget _buildItemRightSection(
+      BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      color: Colors.white,
+      child: TextButton(
+        onPressed: () {},
+        style: TextButton.styleFrom(
+          foregroundColor: Colors.black,
+          backgroundColor: ColorUtils.string2Color('#4161D0'), // 背景颜色
+          minimumSize: const Size(91.5, 30), // 最小宽度和高度
+          padding:
+              const EdgeInsets.symmetric(horizontal: 11.0, vertical: 9), // 内边距
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(5), // 圆角
+            side: BorderSide(
+              color: ColorUtils.string2Color('#4161D0'),
+              width: 1.0,
+            ), // 边框
+          ),
+        ),
+        child: const Text('Open Folder',
+          style: const TextStyle(color: Colors.white,),
+        ),
+      ),
+    );
+  }
+
+  // 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: Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisSize: MainAxisSize.max,
+        children: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 70,
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.start,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                Expanded(child: _buildItemLeftSection(context, ref, item, _vm)),
+                Container(
+                  width: 120,
+                  child: _buildItemRightSection(context, ref, item, _vm),
+                  // child: TextButton(onPressed: (){}, child: Text("fdsfds")),
+                ),
+              ],
+            ).paddingOnly(left: 20,right: 20),
+          ).constrained(
+            minHeight: 70,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item);
+      }),
+    ).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(documentsVmProvider.notifier);
+
+    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)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/documents/page/documents_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+DocumentsState documentsStateFromJson(String str) => DocumentsState.fromJson(json.decode(str));
+
+String documentsStateToJson(DocumentsState data) => json.encode(data.toJson());
+
+class DocumentsState {
+  DocumentsState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory DocumentsState.fromJson(Map<dynamic, dynamic> json) => DocumentsState(
+    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,
+  };
+
+  DocumentsState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return DocumentsState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/documents/repository/documents_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 '../page/documents_state.dart';
+part 'documents_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+DocumentsRepository documentsRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return DocumentsRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class DocumentsRepository {
+  DioEngine dioEngine;
+
+  DocumentsRepository({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 = DocumentsState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<DocumentsState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 28 - 0
packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.g.dart

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

+ 105 - 0
packages/cpt_notice_board/lib/modules/documents/vm/documents_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 '../page/documents_state.dart';
+import '../repository/documents_repository.dart';
+part 'documents_vm.g.dart';
+
+@riverpod
+class DocumentsVm extends _$DocumentsVm {
+  late DocumentsRepository documentsRepository;
+  DocumentsState initState() {
+    return DocumentsState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title": "18 Sep 2024 BIK 39#09-XX 1337 psd 1001 sqft",
+          "price": "\$1.338 M",
+        },
+        {
+          "id": 2,
+          "title": "18 Sep 2024 BIK 39#09-XX 1337 psd 1001 sqft",
+          "price": "\$1.338 M",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  DocumentsState build() {
+    // 引入数据仓库
+    documentsRepository = ref.read(documentsRepositoryProvider);
+    // 初始化状态
+    DocumentsState 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 documentsRepository.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_notice_board/lib/modules/documents/vm/documents_vm.g.dart

@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'documents_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$documentsVmHash() => r'17fac5225fa9da020cd0a78c745412eb3ded2770';
+
+/// See also [DocumentsVm].
+@ProviderFor(DocumentsVm)
+final documentsVmProvider =
+    AutoDisposeNotifierProvider<DocumentsVm, DocumentsState>.internal(
+  DocumentsVm.new,
+  name: r'documentsVmProvider',
+  debugGetCreateSourceHash:
+      const bool.fromEnvironment('dart.vm.product') ? null : _$documentsVmHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$DocumentsVm = AutoDisposeNotifier<DocumentsState>;
+// 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_notice_board/lib/modules/event/page/event_page.dart

@@ -0,0 +1,130 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_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/notice_board_page_router.dart';
+import '../vm/event_vm.dart';
+
+@RoutePage()
+class EventPage extends HookConsumerWidget {
+  const EventPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const EventPageRoute());
+    } else {
+      appRouter.push(const EventPageRoute());
+    }
+  }
+
+  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), // 设置字体大小
+      ),
+    );
+  }
+
+  Widget _buildItemRightSection(
+      BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.green,
+      child: Text(
+        item['price'],
+        style: const TextStyle(
+            fontSize: 14.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w400), // 设置字体大小
+      ),
+    );
+  }
+
+  // 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: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 100,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                _buildItemLeftSection(context, ref, item, _vm)
+                    .marginOnly(bottom: 5),
+                _buildItemRightSection(context, ref, item, _vm),
+              ],
+            ).paddingOnly(left: 20, right: 20),
+          ).constrained(
+            minHeight: 117.5,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item['title']);
+      }),
+    ).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(eventVmProvider.notifier);
+
+    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)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/event/page/event_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+EventState eventStateFromJson(String str) => EventState.fromJson(json.decode(str));
+
+String eventStateToJson(EventState data) => json.encode(data.toJson());
+
+class EventState {
+  EventState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory EventState.fromJson(Map<dynamic, dynamic> json) => EventState(
+    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,
+  };
+
+  EventState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return EventState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/event/repository/event_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 '../page/event_state.dart';
+part 'event_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+EventRepository eventRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return EventRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class EventRepository {
+  DioEngine dioEngine;
+
+  EventRepository({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 = EventState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<EventState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_notice_board/lib/modules/event/repository/event_repository.g.dart

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

+ 105 - 0
packages/cpt_notice_board/lib/modules/event/vm/event_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 '../page/event_state.dart';
+import '../repository/event_repository.dart';
+part 'event_vm.g.dart';
+
+@riverpod
+class EventVm extends _$EventVm {
+  late EventRepository eventRepository;
+  EventState initState() {
+    return EventState(
+      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
+  EventState build() {
+    // 引入数据仓库
+    eventRepository = ref.read(eventRepositoryProvider);
+    // 初始化状态
+    EventState 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 eventRepository.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_notice_board/lib/modules/event/vm/event_vm.g.dart

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

+ 148 - 67
packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart

@@ -1,11 +1,15 @@
-import 'package:cs_resources/theme/theme_config.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/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/my_load_image.dart';
-import 'package:cs_resources/generated/assets.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
 import 'package:widgets/my_appbar.dart';
+import 'package:cs_resources/generated/assets.dart';
+
 import '../../../router/page/notice_board_page_router.dart';
 import '../../notice_board/vm/notice_board_view_model.dart';
 
@@ -22,76 +26,153 @@ class NoticeBoardPage extends HookConsumerWidget {
     }
   }
 
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.read(noticeBoardViewModelProvider.notifier);
-
-    return Scaffold(
-      // appBar: MyAppBar.titleBar(context, "Test Title"),
-      body: Container(
-        child: Column(
-          children: [
-
-            MyAppBar.titleBar(context, "Test Title"),
-            const Padding(
-              padding: EdgeInsets.fromLTRB(15, 0, 15, 30),
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+  // 顶部tab 切换
+  Widget _buildTopSection(BuildContext context, WidgetRef ref, _vm) {
+    final topSectionsData = _vm.topSectionsData;
+    // 监听 curIdx 的变化
+    final curIdx =
+        ref.watch(noticeBoardVmProvider.select((value) => value.curIdx));
+    return Container(
+      color: Colors.white,
+      child: Center(
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: List.generate(topSectionsData.length, (index) {
+            final item = topSectionsData[index];
+            return Flexible(
+              flex: 1,
+              child: Column(
                 children: [
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardAnnouncementIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Announcement",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardEventIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Event",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardDocumentsIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Documents",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
+                  MyAssetImage(
+                    item['icon'],
+                    width: MediaQuery.of(context).size.width /
+                            topSectionsData.length -
+                        36,
+                    height: 70,
+                  ).onTap(
+                    () {
+                      _vm.switchPage(index, context);
+                    },
+                    type: ClickType.throttle,
+                  ),
+                  SizedBox.fromSize(size: const Size(0, 9)),
+                  Text(
+                    item['title'],
+                    maxLines: 1, // 设置最大行数为2
+                    overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+                    style: TextStyle(
+                        fontSize: 13.0,
+                        color: curIdx == index
+                            ? ColorUtils.string2Color('#4161D0')
+                            : Colors.black,
+                        fontWeight: FontWeight.w500), // 设置字体大小
+                  ),
                 ],
               ),
-            ),
-          ],
+            ).marginOnly(left: 18, right: 18, top: 10, bottom: 10);
+          }),
         ),
       ),
     );
   }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(noticeBoardVmProvider.notifier);
+    return DefaultTabController(
+      length: 4,
+      child: Scaffold(
+          appBar: AppBar(
+            title: const Text("Property"),
+            bottomOpacity: 0.0, // 取消下横线
+            titleTextStyle: const TextStyle(color: Colors.black),
+          ),
+          body: Row(
+            children: [
+              Expanded(
+                child: Column(
+                  children: [
+                    _buildTopSection(context, ref, _vm),
+                    const Expanded(
+                      child: AutoRouter(),
+                    )
+                  ],
+                ),
+              )
+            ],
+          )),
+    );
+  }
+  // @override
+  // Widget build(BuildContext context, WidgetRef ref) {
+  //   final _viewModel = ref.read(noticeBoardVmProvider.notifier);
+  //   return Scaffold(
+  //     // appBar: MyAppBar.titleBar(context, "Test Title"),
+  //     body: Container(
+  //       child: Column(
+  //         children: [
+
+  //           MyAppBar.titleBar(context, "Test Title"),
+  //           const Padding(
+  //             padding: EdgeInsets.fromLTRB(15, 0, 15, 30),
+  //             child: Row(
+  //               mainAxisAlignment: MainAxisAlignment.spaceBetween,
+  //               children: [
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardAnnouncementIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Announcement",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardEventIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Event",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardDocumentsIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Documents",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //               ],
+  //             ),
+  //           ),
+  //         ],
+  //       ),
+  //     ),
+  //   );
+  // }
 }

+ 99 - 2
packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.dart

@@ -1,14 +1,111 @@
 
+// import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+// part 'notice_board_view_model.g.dart';
+
+// @riverpod
+// class NoticeBoardViewModel extends _$NoticeBoardViewModel {
+
+//   @override
+//   void build(){
+
+//   }
+
+// }
+
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+
+// import '../../ioan/property_ioan_page.dart';
+import '../../announ/page/announ_page.dart';
+import '../../documents/page/documents_page.dart';
+import '../../event/page/event_page.dart';
 
 part 'notice_board_view_model.g.dart';
 
+
+class NoticeBoardVmState {
+  List<Map<String, dynamic>>? topSectionsData;
+  int? curIdx;
+
+  NoticeBoardVmState({
+    List<Map<String, dynamic>>? topSectionsData,
+    this.curIdx = 0,
+  }) : topSectionsData = topSectionsData?? [
+    {
+      "title": "Announcement",
+      "icon": Assets.noticeBoardAnnouncementIcon,
+      "pageStartInstanceFn": AnnounPage.startInstance,
+      "page": const AnnounPage(),
+    },
+    {
+      "title": "Event",
+      "icon": Assets.noticeBoardEventIcon,
+      "pageStartInstanceFn": EventPage.startInstance,
+      "page": const EventPage(),
+    },
+    {
+      "title": "Documents",
+      "icon": Assets.noticeBoardDocumentsIcon,
+      "pageStartInstanceFn": DocumentsPage.startInstance,
+      "page": const DocumentsPage(),
+    },
+  ];
+
+  NoticeBoardVmState copyWith({
+    List<Map<String, dynamic>>? topSectionsData,
+    int? curIdx = 0,
+  }) {
+    return NoticeBoardVmState(
+      topSectionsData: topSectionsData ?? this.topSectionsData,
+      curIdx: curIdx ?? 0,
+    );
+  }
+}
+
 @riverpod
-class NoticeBoardViewModel extends _$NoticeBoardViewModel {
+class NoticeBoardVm extends _$NoticeBoardVm {
+  get topSectionsData => state.topSectionsData;
+
+  NoticeBoardVmState initState() {
+    return NoticeBoardVmState();
+  }
 
   @override
-  void build(){
+  NoticeBoardVmState build(){
+    final state = initState();
+    Log.d("--------------------------build---------------------");
 
+    // 初始时导航到子路由
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      switchPage(state.curIdx ?? 0, null, true);
+    });
+
+    return state;
+  }
+
+  // 页面切换
+  switchPage(int index,BuildContext? context, [bool? isFirstInitSwitch] ){
+    if(state.curIdx != index){
+      state = state.copyWith(curIdx: index);
+      final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+      // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+      final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+      pageStartInstanceFn(context:context);
+    }else {
+      if(isFirstInitSwitch??false){
+        final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+        // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+        final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+        pageStartInstanceFn(context:context);
+      }
+    }
   }
 
 }
+
+

+ 9 - 10
packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.g.dart

@@ -6,22 +6,21 @@ part of 'notice_board_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$noticeBoardViewModelHash() =>
-    r'ef467d39ec1baea3c118dbb21e348acb2d219e83';
+String _$noticeBoardVmHash() => r'35dfbf4845c7dca80ef6f737fbc529cb1f232a4f';
 
-/// See also [NoticeBoardViewModel].
-@ProviderFor(NoticeBoardViewModel)
-final noticeBoardViewModelProvider =
-    AutoDisposeNotifierProvider<NoticeBoardViewModel, void>.internal(
-  NoticeBoardViewModel.new,
-  name: r'noticeBoardViewModelProvider',
+/// See also [NoticeBoardVm].
+@ProviderFor(NoticeBoardVm)
+final noticeBoardVmProvider =
+    AutoDisposeNotifierProvider<NoticeBoardVm, NoticeBoardVmState>.internal(
+  NoticeBoardVm.new,
+  name: r'noticeBoardVmProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
       ? null
-      : _$noticeBoardViewModelHash,
+      : _$noticeBoardVmHash,
   dependencies: null,
   allTransitiveDependencies: null,
 );
 
-typedef _$NoticeBoardViewModel = AutoDisposeNotifier<void>;
+typedef _$NoticeBoardVm = AutoDisposeNotifier<NoticeBoardVmState>;
 // 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

+ 25 - 4
packages/cpt_notice_board/lib/router/page/notice_board_page_router.dart

@@ -4,7 +4,9 @@ import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 
 import '../../modules/notice_board/page/notice_board_page.dart';
-
+import '../../modules/announ/page/announ_page.dart';
+import '../../modules/event/page/event_page.dart';
+import '../../modules/documents/page/documents_page.dart';
 
 part 'notice_board_page_router.gr.dart';
 
@@ -15,7 +17,26 @@ part 'notice_board_page_router.gr.dart';
 class NoticeBoardPageRouter extends _$NoticeBoardPageRouter {
   @override
   List<AutoRoute> get routes => [
-
-    CustomRoute(page: NoticeBoardPageRoute.page, path: RouterPath.noticeBoard, transitionsBuilder: applySlideTransition),
-  ];
+        CustomRoute(
+            page: NoticeBoardPageRoute.page,
+            path: RouterPath.noticeBoard,
+            transitionsBuilder: applySlideTransition,
+            children: [
+              CustomRoute(
+                page: AnnounPageRoute.page,
+                path: RouterPath.announ,
+                transitionsBuilder: applySlideTransition,
+              ),
+              CustomRoute(
+                page: EventPageRoute.page,
+                path: RouterPath.event,
+                transitionsBuilder: applySlideTransition,
+              ),
+              CustomRoute(
+                page: DocumentsPageRoute.page,
+                path: RouterPath.documents,
+                transitionsBuilder: applySlideTransition,
+              ),
+            ]),
+      ];
 }

+ 61 - 1
packages/cpt_notice_board/lib/router/page/notice_board_page_router.gr.dart

@@ -15,16 +15,76 @@ abstract class _$NoticeBoardPageRouter extends RootStackRouter {
 
   @override
   final Map<String, PageFactory> pagesMap = {
+    AnnounPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const AnnounPage(),
+      );
+    },
+    DocumentsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const DocumentsPage(),
+      );
+    },
+    EventPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const EventPage(),
+      );
+    },
     NoticeBoardPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const NoticeBoardPage(),
       );
-    }
+    },
   };
 }
 
 /// generated route for
+/// [AnnounPage]
+class AnnounPageRoute extends PageRouteInfo<void> {
+  const AnnounPageRoute({List<PageRouteInfo>? children})
+      : super(
+          AnnounPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'AnnounPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [DocumentsPage]
+class DocumentsPageRoute extends PageRouteInfo<void> {
+  const DocumentsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          DocumentsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'DocumentsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [EventPage]
+class EventPageRoute extends PageRouteInfo<void> {
+  const EventPageRoute({List<PageRouteInfo>? children})
+      : super(
+          EventPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'EventPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [NoticeBoardPage]
 class NoticeBoardPageRoute extends PageRouteInfo<void> {
   const NoticeBoardPageRoute({List<PageRouteInfo>? children})

+ 32 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart

@@ -0,0 +1,32 @@
+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/profile_page_router.dart';
+import 'my_estate_view_model.dart';
+
+@RoutePage()
+class MyEstatePage extends HookConsumerWidget {
+  const MyEstatePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const MyEstatePageRoute());
+    } else {
+      appRouter.push(const MyEstatePageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(myEstateViewModelProvider.notifier);
+
+    return Scaffold(
+      appBar: AppBar(title: Text("Profile Edit Page")),
+      body: Center(
+        child: Text("Profile Edit Page"),
+      ),
+    );
+  }
+}

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

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

+ 13 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart

@@ -0,0 +1,13 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'my_estate_state.dart';
+
+part 'my_estate_view_model.g.dart';
+
+@riverpod
+class MyEstateViewModel extends _$MyEstateViewModel {
+  @override
+  MyEstateState build() {
+    return MyEstateState();
+  }
+}

+ 26 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.g.dart

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

+ 32 - 0
packages/cpt_profile/lib/modules/my_household/my_household_page.dart

@@ -0,0 +1,32 @@
+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/profile_page_router.dart';
+import 'my_household_view_model.dart';
+
+@RoutePage()
+class MyHouseholdPage extends HookConsumerWidget {
+  const MyHouseholdPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const MyHouseholdPageRoute());
+    } else {
+      appRouter.push(const MyHouseholdPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(myHouseholdViewModelProvider.notifier);
+
+    return Scaffold(
+      appBar: AppBar(title: Text("Profile Edit Page")),
+      body: Center(
+        child: Text("Profile Edit Page"),
+      ),
+    );
+  }
+}

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

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

+ 13 - 0
packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart

@@ -0,0 +1,13 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'my_household_state.dart';
+
+part 'my_household_view_model.g.dart';
+
+@riverpod
+class MyHouseholdViewModel extends _$MyHouseholdViewModel {
+  @override
+  MyHouseholdState build() {
+    return MyHouseholdState();
+  }
+}

+ 27 - 0
packages/cpt_profile/lib/modules/my_household/my_household_view_model.g.dart

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

+ 210 - 4
packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart

@@ -1,9 +1,20 @@
+import 'package:cpt_profile/modules/profile_edit/profile_edit_state.dart';
 import 'package:cpt_profile/modules/profile_edit/profile_edit_view_model.dart';
 import 'package:cpt_profile/router/page/profile_page_router.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
 @RoutePage()
 class ProfileEditPage extends HookConsumerWidget {
@@ -20,12 +31,207 @@ class ProfileEditPage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.watch(profileEditViewModelProvider.notifier);
+    final viewModel = ref.watch(profileEditViewModelProvider.notifier);
+    final state = ref.watch(profileEditViewModelProvider);
 
     return Scaffold(
-      appBar: AppBar(title: Text("Profile Edit Page")),
-      body: Center(
-        child: Text("Profile Edit Page"),
+      appBar: MyAppBar.appBar(context, S.current.edit_profile,backgroundColor: context.appColors.whiteBG),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 15),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Center(
+                child: Container(
+                  width: 80,
+                  height: 80,
+                  decoration: BoxDecoration(color: context.appColors.avatarBg, shape: BoxShape.circle),
+                  child: Stack(
+                    children: [
+                      //默认的占位图
+                      Visibility(
+                        visible: true,
+                        child: const Align(
+                          alignment: Alignment.bottomCenter,
+                          child: MyAssetImage(
+                            Assets.profileEditProfileAvatarDefault,
+                            width: 49,
+                            height: 64,
+                          ),
+                        ),
+                      ),
+
+                      //用户的头像
+                      Visibility(
+                        visible: false,
+                        child: MyLoadImage(
+                          "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                          width: 80,
+                          height: 80,
+                          isCircle: true,
+                        ),
+                      ),
+
+                      //底部的背景色
+                      const Align(
+                        alignment: Alignment.bottomCenter,
+                        child: MyAssetImage(
+                          Assets.profileEditProfileAvatarBottom,
+                          width: 71,
+                          height: 21.5,
+                        ),
+                      ),
+                      //照相机Icon
+                      const Align(
+                        alignment: Alignment.bottomCenter,
+                        child: MyAssetImage(
+                          Assets.profileEditProfileAdd,
+                          width: 12,
+                          height: 11.5,
+                        ),
+                      ).marginOnly(bottom: 4),
+                    ],
+                  ),
+                ).onTap((){
+                  viewModel.showAvatarEditDialog(context);
+                }),
+              ).marginOnly(top: 23),
+
+              // 表单 - 名
+              MyTextView(
+                S.current.first_name,
+                fontSize: 17,
+                marginTop: 33,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "first_name",
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['last_name']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 姓
+              MyTextView(
+                S.current.last_name,
+                fontSize: 17,
+                marginTop: 15,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "last_name",
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['email']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 邮箱
+              MyTextView(
+                S.current.email,
+                fontSize: 17,
+                marginTop: 15,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "email",
+                textInputType: TextInputType.emailAddress,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                },
+              ),
+
+              //提交
+              MyButton(
+                onPressed: viewModel.submitEdit,
+                text: S.current.submit,
+                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,
+    ProfileEditState state,
+    String 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(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintText: state.formData[key]!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['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,
       ),
     );
   }

+ 133 - 0
packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart

@@ -0,0 +1,133 @@
+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:plugin_platform/engine/toast/toast_engine.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 {
+  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) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        Container(
+          width: double.infinity,
+          padding: const EdgeInsets.only(top: 31.5, bottom: 30.5, left: 27.5, right: 27.5),
+          decoration: BoxDecoration(
+            color: context.appColors.whiteBG,
+            borderRadius: const BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Container(
+                width: double.infinity,
+                height: 50,
+                decoration: const BoxDecoration(
+                  color: Color(0XFFE9ECF8),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    const MyAssetImage(
+                      Assets.profileEditDialogUpload,
+                      width: 27.5,
+                      height: 27.5,
+                    ),
+                    MyTextView(
+                      S.current.upload_a_photo, 
+                      fontSize: 16,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                      marginLeft: 12,
+                    ),
+                  ],
+                ).onTap((){
+                  onCancel();
+                  photoAction.call();
+                }),
+              ),
+
+              //分割线
+              Stack(
+                children: [
+                  const MyAssetImage(Assets.profileEditXuLine, width: 270, height: 1).marginOnly(top: 10),
+                  Align(
+                    alignment: Alignment.center,
+                    child: MyTextView(
+                      S.current.or,
+                      textColor: context.appColors.textDarkGray,
+                      fontSize: 16,
+                      isFontMedium: true,
+                    ),
+                  ),
+                ],
+              ).marginOnly(top: 26, bottom: 6),
+
+              //图片九宫格
+              GridView.builder(
+                shrinkWrap: true,
+                physics: const NeverScrollableScrollPhysics(),
+                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+                  crossAxisCount: 3, // 每行显示的列数
+                  mainAxisSpacing: 20.0, // 主轴(上下)的间距
+                  crossAxisSpacing: 15.0, // 交叉轴(左右)的间距
+                  childAspectRatio: 1, // 宽高比例
+                ),
+                itemCount: otherImages.length,
+                itemBuilder: (context, index) {
+                  return Center(
+                    child: MyLoadImage(otherImages[index]).onTap((){
+                      onCancel();
+                      otherAction.call(otherImages[index]);
+                    }),
+                  );
+                },
+              ),
+            ],
+          ),
+        ),
+        const MyAssetImage(
+          Assets.profileEditDialogDelete,
+          width: 25,
+          height: 25.5,
+        ).onTap(() {
+          onCancel();
+        }).marginOnly(top: 23.5),
+      ],
+    ).constrained(width: 325);
+  }
+
+//取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

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

@@ -0,0 +1,49 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class ProfileEditState{
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  String? avatarPath;  //头像的路径或Uri
+
+  // ===================================  Begin  ↓  ===================================
+
+  ProfileEditState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.avatarPath,
+  }) : formData = formData ??
+      {
+        'first_name': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.first_name,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'last_name': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.last_name,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'email': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.email,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+      };
+
+  ProfileEditState copyWith({
+    String? avatarPath,
+  }) {
+    return ProfileEditState(
+      formData: this.formData,
+      avatarPath: avatarPath ?? this.avatarPath,
+    );
+  }
+
+}

+ 56 - 3
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart

@@ -1,13 +1,66 @@
-
+import 'package:cpt_profile/modules/profile_edit/dialog/avatar_edit_dialog.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/log_utils.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 {
-
   @override
-  void build(){
+  ProfileEditState build() {
+    return ProfileEditState();
+  }
+
+  /// 提交编辑用户信息
+  void submitEdit() {
+    final FocusNode firstNameFocusNode = state.formData['first_name']!['focusNode'];
+    final FocusNode lastNameFocusNode = state.formData['last_name']!['focusNode'];
+    final FocusNode emailFocusNode = state.formData['email']!['focusNode'];
+
+    firstNameFocusNode.unfocus();
+    lastNameFocusNode.unfocus();
+    emailFocusNode.unfocus();
+
+    final TextEditingController firstNameController = state.formData['first_name']!['controller'];
+    final TextEditingController lastNameController = state.formData['last_name']!['controller'];
+    final TextEditingController emailController = state.formData['email']!['controller'];
 
+    final firstName = firstNameController.text;
+    final lastName = lastNameController.text;
+    final email = emailController.text;
+
+    Log.d('当前待提交的 firstName:$firstName lastName:$lastName email:$email');
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求发送验证码 firstName:$firstName lastName:$lastName email:$email ');
+
+    appRouter.maybePop();
   }
 
+  //去编辑头像页面
+  void showAvatarEditDialog(BuildContext context) {
+    DialogEngine.show(
+        widget: AvatarEditDialog(
+      otherAction: (path) {
+        ToastEngine.show("点击了图片:$path");
+      },
+      photoAction: () {
+        //选择相机相册
+        _pickPhoto(context);
+      },
+    ));
+  }
+
+  //相机相册选择
+  void _pickPhoto(BuildContext context) {
+    ImagePickerUtils().show(context, (path) {
+      ToastEngine.show("选中了图片:$path");
+    });
+  }
 }

+ 0 - 0
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.g.dart


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio