Sfoglia il codice sorgente

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

“shanwenxin” 1 settimana fa
parent
commit
ec3ec51fb9
93 ha cambiato i file con 3282 aggiunte e 449 eliminazioni
  1. 0 99
      packages/cpt_community/lib/components/custom_tabs.dart
  2. 0 29
      packages/cpt_community/lib/components/custom_tabs_state.dart
  3. 0 55
      packages/cpt_community/lib/components/custom_tabs_vm.dart
  4. 0 25
      packages/cpt_community/lib/components/custom_tabs_vm.g.dart
  5. 53 18
      packages/cpt_community/lib/modules/community/community_page.dart
  6. 0 104
      packages/cpt_community/lib/modules/community/community_page1.dart
  7. 14 0
      packages/cpt_community/lib/modules/community/community_state.dart
  8. 14 2
      packages/cpt_community/lib/modules/community/community_vm.dart
  9. 1 1
      packages/cpt_community/lib/modules/community/community_vm.g.dart
  10. 38 0
      packages/cpt_community/lib/modules/garagesale/garagesale_detail/garagesale_detail_page.dart
  11. 38 0
      packages/cpt_community/lib/modules/garagesale/garagesale_myposts/garagesale_myposts_page.dart
  12. 194 4
      packages/cpt_community/lib/modules/garagesale/garagesale_page.dart
  13. 38 0
      packages/cpt_community/lib/modules/garagesale/garagesale_post/garagesale_post_page.dart
  14. 71 0
      packages/cpt_community/lib/modules/garagesale/garagesale_repository.dart
  15. 28 0
      packages/cpt_community/lib/modules/garagesale/garagesale_repository.g.dart
  16. 69 0
      packages/cpt_community/lib/modules/garagesale/garagesale_state.dart
  17. 110 0
      packages/cpt_community/lib/modules/garagesale/garagesale_tabs.dart
  18. 133 2
      packages/cpt_community/lib/modules/garagesale/garagesale_vm.dart
  19. 3 3
      packages/cpt_community/lib/modules/garagesale/garagesale_vm.g.dart
  20. 38 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_detail/newsfeed_detail_page.dart
  21. 38 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_myposts/newsfeed_myposts_page.dart
  22. 78 29
      packages/cpt_community/lib/modules/newsfeed/newsfeed_page.dart
  23. 155 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_page.dart
  24. 8 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_page_state.dart
  25. 47 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_vm.dart
  26. 26 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_vm.g.dart
  27. 6 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_state.dart
  28. 111 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_tabs.dart
  29. 62 2
      packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.dart
  30. 1 1
      packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.g.dart
  31. 37 1
      packages/cpt_community/lib/router/page/community_page_router.dart
  32. 120 0
      packages/cpt_community/lib/router/page/community_page_router.gr.dart
  33. 253 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart
  34. 54 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart
  35. 103 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart
  36. 27 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart
  37. 74 0
      packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart
  38. 215 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart
  39. 18 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart
  40. 15 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart
  41. 27 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart
  42. 4 1
      packages/cpt_main/lib/modules/feedback/history/feedback_history.dart
  43. 2 1
      packages/cpt_main/lib/modules/feedback/item_feedback.dart
  44. 4 1
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart
  45. 2 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_large.dart
  46. 3 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_small.dart
  47. 3 3
      packages/cpt_main/lib/modules/me/me_view_model.dart
  48. 10 19
      packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart
  49. 0 6
      packages/cpt_main/lib/modules/visitor/register/visitor_register_state.dart
  50. 1 3
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart
  51. 1 1
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.g.dart
  52. 6 0
      packages/cpt_main/lib/router/page/main_page_router.dart
  53. 60 0
      packages/cpt_main/lib/router/page/main_page_router.gr.dart
  54. 32 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart
  55. 3 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart
  56. 13 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart
  57. 26 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.g.dart
  58. 32 0
      packages/cpt_profile/lib/modules/my_household/my_household_page.dart
  59. 3 0
      packages/cpt_profile/lib/modules/my_household/my_household_state.dart
  60. 13 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart
  61. 27 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.g.dart
  62. 210 4
      packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart
  63. 133 0
      packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart
  64. 49 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart
  65. 56 3
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart
  66. 4 4
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.g.dart
  67. 1 1
      packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.g.dart
  68. 1 1
      packages/cpt_profile/lib/modules/setting/setting_view_model.g.dart
  69. 8 8
      packages/cpt_profile/lib/router/component/profile_component_service_impl.dart
  70. 4 0
      packages/cpt_profile/lib/router/page/profile_page_router.dart
  71. 40 0
      packages/cpt_profile/lib/router/page/profile_page_router.gr.dart
  72. 3 0
      packages/cpt_property/lib/modules/ioan/property_ioan_page.dart
  73. 1 0
      packages/cs_plugin_platform/lib/engine/image/image_nine_grid.dart
  74. 2 1
      packages/cs_plugin_platform/lib/platform_export.dart
  75. BIN
      packages/cs_resources/assets/profile/edit_dialog_delete.webp
  76. BIN
      packages/cs_resources/assets/profile/edit_dialog_upload.webp
  77. BIN
      packages/cs_resources/assets/profile/edit_profile_add.webp
  78. BIN
      packages/cs_resources/assets/profile/edit_profile_avatar_bottom.webp
  79. BIN
      packages/cs_resources/assets/profile/edit_profile_avatar_default.webp
  80. BIN
      packages/cs_resources/assets/profile/edit_xu_line.webp
  81. 6 0
      packages/cs_resources/lib/generated/assets.dart
  82. 11 2
      packages/cs_resources/lib/generated/intl/messages_en.dart
  83. 9 2
      packages/cs_resources/lib/generated/intl/messages_zh_CN.dart
  84. 9 2
      packages/cs_resources/lib/generated/intl/messages_zh_HK.dart
  85. 72 2
      packages/cs_resources/lib/generated/l10n.dart
  86. 8 1
      packages/cs_resources/lib/l10n/intl_en.arb
  87. 8 1
      packages/cs_resources/lib/l10n/intl_zh_CN.arb
  88. 8 1
      packages/cs_resources/lib/l10n/intl_zh_HK.arb
  89. 6 0
      packages/cs_resources/lib/theme/app_colors_theme.dart
  90. 1 0
      packages/cs_resources/pubspec.yaml
  91. 0 4
      packages/cs_router/lib/componentRouter/profile_service.dart
  92. 6 0
      packages/cs_router/lib/path/router_path.dart
  93. 64 0
      packages/cs_widgets/lib/shatter/picker_container.dart

+ 0 - 99
packages/cpt_community/lib/components/custom_tabs.dart

@@ -1,99 +0,0 @@
-import 'package:cpt_community/components/custom_tabs_state.dart';
-import 'package:cpt_community/components/custom_tabs_state.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:shared/utils/color_utils.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_text_view.dart';
-import 'package:widgets/my_appbar.dart';
-
-import 'custom_tabs_state.dart';
-import 'custom_tabs_vm.dart';
-
-
-class CustomTabs extends HookConsumerWidget {
-  List tabsList;
-  int activeIndex = 0;
-  Widget? Function(BuildContext)? tabItemBuilder;
-  VoidCallback? onClickAction;
-  CustomTabs({Key? key, required this.tabsList, required this.activeIndex, this.onClickAction, this.tabItemBuilder}) :
-        super(key: key);
-
-  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
-
-    // 监听 activeIndex 的变化
-    final activeIndex = ref.watch(customTabsVmProvider.select((state) => state.activeIndex));
-
-    return Container(
-        width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
-        height: 43,
-        padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
-        decoration: index==activeIndex? BoxDecoration(
-          color: index==activeIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
-          borderRadius: BorderRadius.circular(20),
-          boxShadow: [
-            BoxShadow(
-              color: Colors.grey.withOpacity(0.5),
-              spreadRadius: 1,
-              blurRadius: 5,
-              offset: const Offset(0, 2), // changes position of shadow
-            ),
-          ],
-        ): null,
-        child: Row(
-          children: [
-            Expanded(
-              child: Container(
-                alignment: Alignment.center,
-                child: MyTextView(
-                  item['title'],
-                  fontSize: 16,
-                  textAlign: TextAlign.center,
-                  isFontMedium: true,
-                  textColor: index == activeIndex ? Colors.white :ColorUtils.string2Color("#000000"),
-                ),
-              ),
-            ),
-          ],
-        ),
-    ).onTap((){
-      vm.handlerClickTab(index, item);
-    });
-  }
-
-  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm){
-    tabsList = vm.state.tabsList;
-
-    int tabsLength = tabsList.length;
-    return List.generate(tabsLength, (index) {
-      return _buildTabItem(context, ref, vm, tabsList[index], index);
-    });
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final vm = ref.read(customTabsVmProvider.notifier);
-    // 初始化状态,只在第一次构建时执行
-    if (vm.state.tabsList!.isEmpty) {
-      vm.initPropData(tabsList, activeIndex, tabItemBuilder, onClickAction);
-    }
-
-    return SingleChildScrollView(
-      scrollDirection: Axis.horizontal,
-      physics: const BouncingScrollPhysics(),
-      clipBehavior: Clip.none,
-      child: Row(
-        mainAxisSize: MainAxisSize.max,
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: _buildTabs(context, ref, vm),
-      ).constrained(
-        maxWidth:  MediaQuery.of(context).size.width
-      ),
-    );
-  }
-}

+ 0 - 29
packages/cpt_community/lib/components/custom_tabs_state.dart

@@ -1,29 +0,0 @@
-import 'package:flutter/cupertino.dart';
-
-class CustomTabsState {
-  List? tabsList;
-  int? activeIndex;
-  Widget? Function(BuildContext)? tabItemBuilder;
-  VoidCallback? onClickAction;
-
-  CustomTabsState({
-    this.tabsList,
-    this.activeIndex,
-    this.tabItemBuilder,
-    this.onClickAction,
-  });
-
-  CustomTabsState copyWith({
-    List? tabsList,
-    int? activeIndex,
-    Widget? Function(BuildContext)? tabItemBuilder,
-    VoidCallback? onClickAction,
-  }) {
-    return CustomTabsState(
-      tabsList: tabsList ?? this.tabsList,
-      activeIndex: activeIndex ?? this.activeIndex,
-      tabItemBuilder: tabItemBuilder ?? this.tabItemBuilder,
-      onClickAction: onClickAction ?? this.onClickAction,
-    );
-  }
-}

+ 0 - 55
packages/cpt_community/lib/components/custom_tabs_vm.dart

@@ -1,55 +0,0 @@
-
-import 'package:cpt_community/components/custom_tabs_state.dart';
-import 'package:cs_resources/generated/assets.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:plugin_platform/engine/toast/toast_engine.dart';
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:shared/utils/log_utils.dart';
-
-part 'custom_tabs_vm.g.dart';
-
-@riverpod
-class CustomTabsVm extends _$CustomTabsVm {
-
-  CustomTabsState initState(List tabsList, int activeIndex, tabItemBuilder, onClickAction) {
-    CustomTabsState state = CustomTabsState(
-        tabsList: tabsList ?? [],
-        activeIndex: activeIndex ?? 0,
-        tabItemBuilder:tabItemBuilder,
-        onClickAction: onClickAction
-    );
-
-    return state;
-  }
-
-  @override
-  CustomTabsState build(){
-    CustomTabsState state = initState([], 0, null, null);
-    return state;
-  }
-
-
-  Future<void> initPropData(tabsList, activeIndex,tabItemBuilder, onClickAction) async {
-    CustomTabsState newState = state.copyWith(
-        tabsList: tabsList,
-        activeIndex: activeIndex,
-        tabItemBuilder: tabItemBuilder,
-        onClickAction: onClickAction
-    );
-    state = newState;
-  }
-
-  // 点击tab
-  void handlerClickTab(int index, item){
-    CustomTabsState newState = state.copyWith(
-        activeIndex: index
-    );
-    state = newState;
-
-    print("切换后新的 sate, ${state.activeIndex}");
-
-    // ref.invalidate(customTabsVmProvider);
-  }
-
-}

+ 0 - 25
packages/cpt_community/lib/components/custom_tabs_vm.g.dart

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

+ 53 - 18
packages/cpt_community/lib/modules/community/community_page.dart

@@ -1,6 +1,8 @@
 
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.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/color_utils.dart';
@@ -29,8 +31,8 @@ class CommunityPage extends HookConsumerWidget {
     }
 
 
-     Widget _buildTopSection(BuildContext context, WidgetRef ref, _vm, tabsRouter) {
-        final topSectionsData = _vm.topSectionsData;
+     Widget _buildTopSection(BuildContext context, WidgetRef ref, vm, tabsRouter) {
+        final topSectionsData = vm.topSectionsData;
         final currentTabIdx = tabsRouter.activeIndex;
         // 监听 curIdx 的变化
         // final curIdx = ref.watch(communityVmProvider.select((value) => value.curIdx));
@@ -53,7 +55,7 @@ class CommunityPage extends HookConsumerWidget {
                         decoration: BoxDecoration(
                           // color: currentTabIdx == index ? ColorUtils.string2Color('#E6F2FF') : Colors.white,
                           shape: BoxShape.circle, // 设置为圆形
-                          boxShadow: tabsRouter.activeIndex == index ? [
+                          boxShadow: currentTabIdx == index ? [
                             BoxShadow(
                               color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
                               blurRadius: 5, // 设置模糊半径
@@ -94,7 +96,8 @@ class CommunityPage extends HookConsumerWidget {
 
     @override
     Widget build(BuildContext context, WidgetRef ref) {
-        final vm = ref.watch(communityVmProvider.notifier);
+        final vm = ref.read(communityVmProvider.notifier);
+
         return Scaffold(
             appBar: MyAppBar.appBar(
               context,
@@ -102,22 +105,54 @@ class CommunityPage extends HookConsumerWidget {
               backgroundColor: context.appColors.whiteBG,
             ),
             backgroundColor: context.appColors.backgroundDefault,
-          body: AutoTabsRouter.pageView(
-            routes: const [
-              NewsfeedPageRoute(),
-              GaragesalePageRoute(),
-            ],
-            builder: (context, child, pageController) {
-              final tabsRouter = AutoTabsRouter.of(context);
-              return Column(
-                children: [
-                  _buildTopSection(context, ref, vm, tabsRouter),
-                  Expanded(
-                    child: child,
+          body: NestedScrollView(
+              headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled){
+                return <Widget>[
+                  SliverToBoxAdapter(
+                    child: Container(
+                      child: const SizedBox.shrink(),
+                    )
+                  ),
+                  SliverToBoxAdapter(
+                    child: Consumer(
+                      builder: (context, ref, _) {
+                        final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                        final vm = ref.read(communityVmProvider.notifier);
+                        Log.d("community_page---buildTopSection ---${tabsRouter}");
+                        Log.d("community_page---buildTopSection ---${vm.state.curIdx}");
+
+                        // return _buildTopSection(context, ref, vm, tabsRouter);
+                        if(tabsRouter != null){
+                          return _buildTopSection(context, ref, vm, tabsRouter);
+                        }else {
+                          return const SizedBox.shrink();
+                        }
+                      },
+                    ),
                   ),
+                ];
+              },
+              body: AutoTabsRouter.pageView(
+                routes: const [
+                  NewsfeedPageRoute(),
+                  GaragesalePageRoute(),
                 ],
-              );
-            },
+                builder: (context, child, pageController) {
+                  final tabsRouter = AutoTabsRouter.of(context);
+                  // 设置当前的 useTag 0 newsFeed 1 garageSale
+                  vm.setCurrentUseTag(tabsRouter.activeIndex);
+                  // 将tabsRouter 放入 CommunityVmProvider 中
+                  vm.setTabsRouterAndPageController(tabsRouter, pageController);
+                  return Column(
+                    children: [
+                      // _buildTopSection(context, ref, vm, tabsRouter),
+                      Expanded(
+                        child: child,
+                      ),
+                    ],
+                  );
+                },
+              ),
           ),
         );
     }

+ 0 - 104
packages/cpt_community/lib/modules/community/community_page1.dart

@@ -1,104 +0,0 @@
-
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-import 'package:shared/utils/color_utils.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_text_view.dart';
-import 'package:widgets/my_appbar.dart';
-import 'package:cs_resources/theme/app_colors_theme.dart';
-
-import '../../router/page/community_page_router.dart';
-import 'community_vm.dart';
-
-@RoutePage()
-class CommunityPage extends HookConsumerWidget {
-  const CommunityPage({Key? key}) : super(key: key);
-
-  //启动当前页面
-  static void startInstance({BuildContext? context}) {
-    if (context != null) {
-      context.router.push(const CommunityPageRoute());
-    } else {
-      appRouter.push(const CommunityPageRoute());
-    }
-  }
-
-
-  Widget _buildTopSection(BuildContext context, WidgetRef ref, _vm) {
-    final topSectionsData = _vm.topSectionsData;
-    // 监听 curIdx 的变化
-    final curIdx = ref.watch(communityVmProvider.select((value) => value.curIdx));
-    return Container(
-      color: Colors.white,
-      padding: const EdgeInsets.only(top: 30, bottom: 30),
-      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: [
-                  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: 15.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.watch(communityVmProvider.notifier);
-    return Scaffold(
-        appBar: MyAppBar.appBar(
-          context,
-          "Community",
-          backgroundColor: context.appColors.whiteBG,
-        ),
-        backgroundColor: context.appColors.backgroundDefault,
-        body: Row(
-          children: [
-            Expanded(
-              child: Column(
-                children: [
-                  _buildTopSection(context, ref, vm),
-                  const Expanded(
-                    child: AutoRouter(),
-                  )
-                ],
-              ),
-            )
-          ],
-        )
-    );
-  }
-}

+ 14 - 0
packages/cpt_community/lib/modules/community/community_state.dart

@@ -4,12 +4,20 @@ import '../garagesale/garagesale_page.dart';
 import '../newsfeed/newsfeed_page.dart';
 
 class CommunityVmState {
+  int? useTag = 0;
   List<Map<String, dynamic>>? topSectionsData;
   int? curIdx;
 
+  dynamic? tabsRouter;
+  dynamic? pageController;
+
+
   CommunityVmState({
+    this.useTag = 0,
     List<Map<String, dynamic>>? topSectionsData,
     this.curIdx = 0,
+    this.tabsRouter,
+    this.pageController,
   }) : topSectionsData = topSectionsData?? [
     {
       "title": "News Feed",
@@ -26,12 +34,18 @@ class CommunityVmState {
   ];
 
   CommunityVmState copyWith({
+    int? useTag,
     List<Map<String, dynamic>>? topSectionsData,
     int? curIdx = 0,
+    dynamic? tabsRouter,
+    dynamic? pageController,
   }) {
     return CommunityVmState(
+      useTag: useTag ?? this.useTag,
       topSectionsData: topSectionsData ?? this.topSectionsData,
       curIdx: curIdx ?? 0,
+      tabsRouter: tabsRouter ?? this.tabsRouter,
+      pageController: pageController ?? this.pageController,
     );
   }
 }

+ 14 - 2
packages/cpt_community/lib/modules/community/community_vm.dart

@@ -28,10 +28,22 @@ class CommunityVm extends _$CommunityVm {
     return state;
   }
 
+   // 设置当前的 tabsRouter 和 pageController
+  Future setTabsRouterAndPageController(dynamic tabsRouter, dynamic pageController) async{
+    Log.d("setTabsRouterAndPageController---: $tabsRouter");
+    state = await state.copyWith(tabsRouter: tabsRouter, pageController: pageController,curIdx: tabsRouter.activeIndex);
+  }
+
+
+   Future setCurrentUseTag(int useTag) async {
+    state = await state.copyWith(useTag: useTag, curIdx: useTag);
+    Log.d("useTag----: $useTag");
+  }
+
   // 页面切换
-  switchPage(int index,BuildContext? context, [bool? isFirstInitSwitch] ){
+  switchPage(int index,int useTag,BuildContext? context, [bool? isFirstInitSwitch] ){
     if(state.curIdx != index){
-      state = state.copyWith(curIdx: index);
+      state = state.copyWith(curIdx: index, useTag: useTag);
       final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
       // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
       final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});

+ 1 - 1
packages/cpt_community/lib/modules/community/community_vm.g.dart

@@ -6,7 +6,7 @@ part of 'community_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$communityVmHash() => r'0ab443b891a6d85cdaea249f8f2e7e3f9842e8c8';
+String _$communityVmHash() => r'15dfd5c8d9c3d01bab9fc789c21ebe61b292c6f3';
 
 /// See also [CommunityVm].
 @ProviderFor(CommunityVm)

+ 38 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_detail/garagesale_detail_page.dart

@@ -0,0 +1,38 @@
+import 'package:cpt_community/router/page/community_page_router.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/my_appbar.dart';
+
+@RoutePage()
+class GaragesaleDetailPage extends HookConsumerWidget {
+  const GaragesaleDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const GaragesaleDetailPageRoute());
+    } else {
+      appRouter.push(const GaragesaleDetailPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Garage Sale Detail",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Center(
+        child: Text("GaragesaleDetail"),
+      ),
+    );
+  }
+}

+ 38 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_myposts/garagesale_myposts_page.dart

@@ -0,0 +1,38 @@
+import 'package:cpt_community/router/page/community_page_router.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/my_appbar.dart';
+
+@RoutePage()
+class GaragesaleMypostsPage extends HookConsumerWidget {
+  const GaragesaleMypostsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const GaragesaleMypostsPageRoute());
+    } else {
+      appRouter.push(const GaragesaleMypostsPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "My Posts",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Center(
+        child: Text("GaragesaleMyposts"),
+      ),
+    );
+  }
+}

+ 194 - 4
packages/cpt_community/lib/modules/garagesale/garagesale_page.dart

@@ -1,12 +1,27 @@
 
+import 'package:cpt_community/components/newsfeed_card_content.dart';
+import 'package:cpt_community/components/newsfeed_card_footer.dart';
+import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.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/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
+import '../../components/newfeed_card_header.dart';
 import '../../router/page/community_page_router.dart';
+import '../community/community_vm.dart';
+import 'garagesale_tabs.dart';
+
 import 'garagesale_vm.dart';
 
+
 @RoutePage()
 class GaragesalePage extends HookConsumerWidget {
   const GaragesalePage({Key? key}) : super(key: key);
@@ -20,14 +35,189 @@ class GaragesalePage extends HookConsumerWidget {
     }
   }
 
+  Widget _buildTabsSection(BuildContext context, WidgetRef ref, vm){
+    return Container(
+      width: double.infinity,
+      padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
+      child: GaragesaleTabs(
+        tabsList: vm.state.tabsList,
+      ),
+    );
+  }
+
+  Widget _buildPostSection(BuildContext context, WidgetRef ref, vm){
+    return Container(
+      height: 65.5,
+      width: double.infinity,
+      padding: const EdgeInsets.only(left: 20, right: 20),
+      color: Colors.white,
+      child: Row(
+        children: [
+          const MyAssetImage(Assets.communityNesFeed, width: 45,height: 45,),
+          Expanded(
+            child: Row(
+              children: [
+                Expanded(
+                  child: Container(
+                    // height: 65.5,
+                    // color: Colors.blue,
+                    child: MyTextView(
+                      "Sell Item",
+                      textColor: ColorUtils.string2Color('#000000'),
+                      fontSize: 15,
+                      marginLeft: 15,
+                      alignment: Alignment.centerLeft,
+                      textAlign: TextAlign.left,
+                      backgroundColor: ColorUtils.string2Color('#ffffff'),
+                      maxLines: 1,
+                      isFontMedium: true,
+                    ),
+                  ),
+                ),
+                const MyAssetImage(
+                  Assets.communityCamera,
+                  width: 21,
+                  height: 16.5,
+                ),
+              ],
+            ).onTap((){
+              vm.handlerGotoPost(context);
+            }),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildNewsItem(BuildContext context, WidgetRef ref, item, vm){
+    return Container(
+        width: double.infinity,
+        // padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
+        color: Colors.yellow,
+        child: Container(
+          margin: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
+          color: Colors.white,
+          padding: const EdgeInsets.only(left: 15, right: 15,top: 17,bottom: 17),
+          height: 280,
+          child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                // 卡片头部(头像 标题 时间)
+                NewsFeedCardHeader(
+                  title: item['title'],
+                  avator: item['avator'],
+                  time: item['time'],
+                ),
+                const SizedBox(height: 15),
+                // 卡片中间 (文字和图片)
+                Expanded(
+                  child: NewsFeedCardContent(
+                    content: item['content'],
+                    imageUrls: item['imageUrls'],
+                  ),
+                ),
+                const SizedBox(height: 26),
+                // // 卡片底部 (点赞 评论 分享)
+                NewsFeedCardFooter(
+                  isLike: item['isLike'],
+                ),
+              ]
+          ),
+        )
+    );
+  }
+
+  Widget _buildNesFeedList(BuildContext context, WidgetRef ref, vm){
+    // return Container(
+    //   height: 100,
+    //   color: Colors.blue,
+    // );
+    final itemList = vm.state.list?? [];
+    if(itemList.isEmpty){
+      return const Center(child: Text('No Data'));
+    }else {
+      List itemsList = vm.state.list.toList();
+      return ListView.builder(
+        itemCount: itemsList.length,
+        itemBuilder: (context, index) {
+          return _buildNewsItem(context, ref, itemsList[index], vm);
+        },
+      );
+    }
+  }
+
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.read(garagesaleVmProvider.notifier);
+    final vm = ref.read(garagesaleVmProvider.notifier);
 
     return Scaffold(
-      // appBar: AppBar(title: Text("社区")),
-      body: Center(
-        child: Text("garage sale"),
+      backgroundColor: ColorUtils.string2Color("#F2F3F6"),
+      body: Column(
+        children: [
+          _buildTabsSection(context, ref, vm),
+
+          _buildPostSection(context, ref, vm),
+
+          NotificationListener<ScrollNotification>(
+            onNotification: (ScrollNotification notification) {
+              // 检查当前页面是否是可见的
+              bool isDownOrUp = notification.metrics.axis == Axis.vertical;
+              if (notification is UserScrollNotification) {
+                // 检查滚动方向
+                switch (notification.direction) {
+                  case ScrollDirection.forward:
+                    print('Scrolling down');
+                    break;
+                  case ScrollDirection.reverse:
+                    print('Scrolling up');
+                    break;
+                  case ScrollDirection.idle:
+                    print('Scrolling stopped');
+                    break;
+                }
+              } else if (notification is ScrollUpdateNotification) {
+                // 检查滚动位置变化
+                double currentScrollPosition = notification.metrics.pixels;
+                double maxScrollExtent = notification.metrics.maxScrollExtent;
+
+                // 判断是否满足某个条件
+                if (currentScrollPosition > 0 && currentScrollPosition < maxScrollExtent) {
+                  print('Current scroll position: $currentScrollPosition');
+                  // 在这里添加你的条件判断逻辑
+                }
+
+                // 只有当上下滚动时才拦截通知
+                if (notification.metrics.axis == Axis.vertical) {
+                  final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                  final curUseTag = ref.watch(communityVmProvider).useTag;
+
+                  if(curUseTag != 1 ){
+                    // 非当前 页面都阻止滚动
+                    return true; // 返回 true 表示已处理通知
+                  }
+                }
+              }
+              return false; // 返回 false 表示不拦截通知
+            },
+            child: Expanded(
+              child: EasyRefresh(
+                // 上拉加载
+                onLoad: () async{
+                  Log.d("----onLoad");
+                  vm.onLoadData();
+                },
+                // 下拉刷新
+                onRefresh: () async{
+                  Log.d("----onRefresh");
+                  vm.refreshListData();
+                },
+                child: _buildNesFeedList(context, ref, vm),
+              ),
+            ),
+          )
+        ],
       ),
     );
   }

+ 38 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_post/garagesale_post_page.dart

@@ -0,0 +1,38 @@
+import 'package:cpt_community/router/page/community_page_router.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/my_appbar.dart';
+
+@RoutePage()
+class GaragesalePostPage extends HookConsumerWidget {
+  const GaragesalePostPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const GaragesalePostPageRoute());
+    } else {
+      appRouter.push(const GaragesalePostPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Garage Sale Post",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Center(
+        child: Text("GaragesalePost"),
+      ),
+    );
+  }
+}

+ 71 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_repository.dart

@@ -0,0 +1,71 @@
+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 'garagesale_state.dart';
+
+part 'garagesale_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+GaragesaleRepository garagesaleRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return GaragesaleRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class GaragesaleRepository {
+  DioEngine dioEngine;
+
+  GaragesaleRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchGaragesaleList(
+      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 = GaragesaleState.fromMap(json!);
+      //重新赋值data或list
+      return result.convert<GaragesaleState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 28 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_repository.g.dart

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

+ 69 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_state.dart

@@ -0,0 +1,69 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:shared/utils/color_utils.dart';
+
+class GaragesaleState {
+  int? useTag;
+  int? curPage;
+  int? pageSize;
+  int? filterCount;
+  int? activeIndex = 0;
+  List tabsList = [];
+  List? list = [];
+
+
+
+  GaragesaleState copyWith({
+    int? useTag,
+    int? curPage,
+    int? pageSize,
+    int? filterCount,
+    int? activeIndex,
+    List? tabsList,
+    List? list,
+  }) {
+    return GaragesaleState(
+      useTag: useTag ?? this.useTag,
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      filterCount: filterCount ?? this.filterCount,
+      activeIndex: activeIndex ?? this.activeIndex,
+      tabsList: tabsList ?? this.tabsList,
+      list: list ?? this.list,
+    );
+  }
+
+  Map<String, dynamic> toMap() {
+    return {
+      'useTag': this.useTag,
+      'curPage': this.curPage,
+      'pageSize': this.pageSize,
+      'filterCount': this.filterCount,
+      'activeIndex': this.activeIndex,
+      'tabsList': this.tabsList,
+      'list': this.list,
+    };
+  }
+
+  factory GaragesaleState.fromMap(Map<String, dynamic> map) {
+    return GaragesaleState(
+      useTag: map['useTag'] as int,
+      curPage: map['curPage'] as int,
+      pageSize: map['pageSize'] as int,
+      filterCount: map['filterCount'] as int,
+      activeIndex: map['activeIndex'] as int,
+      tabsList: map['tabsList'] as List,
+      list: map['list'] as List,
+    );
+  }
+
+  GaragesaleState({
+    this.useTag,
+    this.curPage,
+    this.pageSize,
+    this.filterCount,
+    this.activeIndex,
+    required this.tabsList,
+    this.list,
+  });
+}

+ 110 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_tabs.dart

@@ -0,0 +1,110 @@
+import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
+
+import '../community/community_vm.dart';
+import '../garagesale/garagesale_vm.dart';
+
+class GaragesaleTabs extends HookConsumerWidget {
+  List tabsList;
+  Widget? Function(BuildContext)? tabItemBuilder;
+  VoidCallback? onClickAction;
+  GaragesaleTabs({
+    Key? key,
+    required this.tabsList,
+    this.onClickAction,
+    this.tabItemBuilder
+  }) : super(key: key);
+
+  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
+    // 监听 activeIndex 的变化
+    final activeIndex = ref.watch(garagesaleVmProvider.select((state) => state.activeIndex));
+
+
+    return Container(
+      width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
+      height: 43,
+      padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
+      decoration: index==activeIndex? BoxDecoration(
+        color: index==activeIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
+        borderRadius: BorderRadius.circular(20),
+        boxShadow: [
+          BoxShadow(
+            color: Colors.grey.withOpacity(0.5),
+            spreadRadius: 1,
+            blurRadius: 5,
+            offset: const Offset(0, 2), // changes position of shadow
+          ),
+        ],
+      ): null,
+      child: Row(
+        children: [
+          Expanded(
+            child: Container(
+              alignment: Alignment.center,
+              child: MyTextView(
+                item['title'],
+                fontSize: 16,
+                textAlign: TextAlign.center,
+                isFontMedium: true,
+                textColor: index == activeIndex ? Colors.white :ColorUtils.string2Color("#000000"),
+              ),
+            ),
+          ),
+        ],
+      ),
+    ).onTap((){
+      vm.handlerClickTab(index, item);
+    });
+  }
+
+  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm){
+
+    int currentUseTag = ref.watch(garagesaleVmProvider.select((state) => state.useTag!));
+
+    List tabsList = ref.read(garagesaleVmProvider).tabsList;
+
+    int tabsLength = tabsList.length;
+
+    return List.generate(tabsLength, (index) {
+      return _buildTabItem(context, ref, vm, tabsList[index], index);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(garagesaleVmProvider.notifier);
+    // 使用useEffect钩子
+    useEffect(() {
+      print('副作用函数执行');
+      // 这里是副作用逻辑
+      // 返回清理函数
+      return () {
+        print('清理函数执行');
+      };
+    }, []); // 空依赖列表意味着这个副作用只在组件挂载时执行一次
+
+    return SingleChildScrollView(
+      scrollDirection: Axis.horizontal,
+      physics: const BouncingScrollPhysics(),
+      clipBehavior: Clip.none,
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: _buildTabs(context, ref, vm),
+      ).constrained(
+          maxWidth:  MediaQuery.of(context).size.width
+      ),
+    );
+  }
+}

+ 133 - 2
packages/cpt_community/lib/modules/garagesale/garagesale_vm.dart

@@ -1,14 +1,145 @@
 
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/path/router_path.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:auto_route/auto_route.dart';
+
+import 'garagesale_state.dart';
+import 'garagesale_repository.dart';
 
 part 'garagesale_vm.g.dart';
 
 @riverpod
 class GaragesaleVm extends _$GaragesaleVm {
-
+  late GaragesaleRepository garagesaleRepository;
+  GaragesaleState initState() {
+    return GaragesaleState(
+        useTag: 1,
+        activeIndex: 0,
+        tabsList: [
+          {
+            'title': 'For Sale',
+            'icon': null,
+            'active': true,
+            'activeTitleColor': Colors.white,
+            'activeTitleFontSize': 16,
+            'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
+          },
+          {
+            'title': 'For Rent',
+            'icon': null,
+            'active': false,
+            'activeTitleColor': Colors.white,
+            'activeTitleFontSize': 16,
+            'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
+          },
+        ],
+        list: [
+          {
+            'id':1,
+            'avator': Assets.communityCamera,
+            'title': '发动机上课士大夫',
+            'isFollow': false,
+            'content': '经典福克斯附件是的开飞机迪斯科封禁端口是否建立四道口附近 ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': true,
+            'likeno': 12
+          },
+          {
+            'id':2,
+            'avator': Assets.communityCamera,
+            'title': '分等级付给的积分多少',
+            'isFollow': true,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': ['https://img.alicdn.com/tfs/TB1h.o9O4MPMeJjy1XaXXcSsFXa-640-360.jpg','https://img.alicdn.com/tfs/TB1h.o9O4MPMeJjy1XaXXcSsFXa-640-360.jpg','https://img.alicdn.com/tfs/TB1h.o9O4MPMeJjy1XaXXcSsFXa-640-360.jpg'],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': true,
+            'likeno': 12
+          },
+        ]
+    );
+  }
   @override
-  void build(){
+  GaragesaleState build(){
+    // 引入数据仓库
+    garagesaleRepository = ref.read(garagesaleRepositoryProvider);
+    // 初始化状态
+    GaragesaleState state = initState();
+    return state;
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----garagesale_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();
+  }
 
+  // 获取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 garagesaleRepository.fetchGaragesaleList(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("----garagesale_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(garagesaleVmProvider);
+    getListData();
+
+  }
+
+
+
+  // 点击发布的按钮 跳转到发布的页面
+  void handlerGotoPost(context){
+    // ComponentServiceManager().communityService.startCommunityPage();
+
+    AutoRouter.of(context).pushNamed(RouterPath.garageSalePost);
+  }
+
+  // 点击tab
+  void handlerClickTab(int index, item){
+    state = state.copyWith(activeIndex: index);
+    print("切换后新的 sate, ${state.tabsList}");
+
+    // ref.invalidate(customTabsVmProvider);
+  }
 }

+ 3 - 3
packages/cpt_community/lib/modules/garagesale/garagesale_vm.g.dart

@@ -6,12 +6,12 @@ part of 'garagesale_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$garagesaleVmHash() => r'd0d07aece7f60fe8f6ef2977f4827ac749dfb58b';
+String _$garagesaleVmHash() => r'd531a4a4393b7310a34957d2636d8be9f4a3d697';
 
 /// See also [GaragesaleVm].
 @ProviderFor(GaragesaleVm)
 final garagesaleVmProvider =
-    AutoDisposeNotifierProvider<GaragesaleVm, void>.internal(
+    AutoDisposeNotifierProvider<GaragesaleVm, GaragesaleState>.internal(
   GaragesaleVm.new,
   name: r'garagesaleVmProvider',
   debugGetCreateSourceHash:
@@ -20,6 +20,6 @@ final garagesaleVmProvider =
   allTransitiveDependencies: null,
 );
 
-typedef _$GaragesaleVm = AutoDisposeNotifier<void>;
+typedef _$GaragesaleVm = AutoDisposeNotifier<GaragesaleState>;
 // 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

+ 38 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_detail/newsfeed_detail_page.dart

@@ -0,0 +1,38 @@
+import 'package:cpt_community/router/page/community_page_router.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/my_appbar.dart';
+
+@RoutePage()
+class NewsfeedDetailPage extends HookConsumerWidget {
+  const NewsfeedDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const NewsfeedDetailPageRoute());
+    } else {
+      appRouter.push(const NewsfeedDetailPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "News Feed Detail",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Center(
+        child: Text("NewsfeedDetail"),
+      ),
+    );
+  }
+}

+ 38 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_myposts/newsfeed_myposts_page.dart

@@ -0,0 +1,38 @@
+import 'package:cpt_community/router/page/community_page_router.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/my_appbar.dart';
+
+@RoutePage()
+class NewsfeedMypostsPage extends HookConsumerWidget {
+  const NewsfeedMypostsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const NewsfeedMypostsPageRoute());
+    } else {
+      appRouter.push(const NewsfeedMypostsPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "My Posts",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Center(
+        child: Text("NewsfeedMyposts"),
+      ),
+    );
+  }
+}

+ 78 - 29
packages/cpt_community/lib/modules/newsfeed/newsfeed_page.dart

@@ -1,10 +1,10 @@
 
-import 'package:cpt_community/components/custom_tabs.dart';
 import 'package:cpt_community/components/newsfeed_card_content.dart';
 import 'package:cpt_community/components/newsfeed_card_footer.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter/rendering.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/color_utils.dart';
@@ -16,6 +16,8 @@ import 'package:widgets/widget_export.dart';
 
 import '../../components/newfeed_card_header.dart';
 import '../../router/page/community_page_router.dart';
+import '../community/community_vm.dart';
+import 'newsfeed_tabs.dart';
 import 'newsfeed_vm.dart';
 
 @RoutePage()
@@ -35,7 +37,9 @@ class NewsfeedPage extends HookConsumerWidget {
     return Container(
       width: double.infinity,
       padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
-      child: CustomTabs(tabsList: vm.state.tabsList, activeIndex: vm.state.activeIndex),
+      child: NewsfeedTabs(
+        tabsList: vm.state.tabsList,
+      ),
     );
   }
 
@@ -48,38 +52,42 @@ class NewsfeedPage extends HookConsumerWidget {
       child: Row(
         children: [
           const MyAssetImage(Assets.communityNesFeed, width: 45,height: 45,),
-          Expanded(
-            child: Container(
-              // height: 65.5,
-              // color: Colors.blue,
-              child: MyTextView(
-                "What’s on your mind?",
-                textColor: ColorUtils.string2Color('#000000'),
-                fontSize: 15,
-                marginLeft: 15,
-                alignment: Alignment.centerLeft,
-                textAlign: TextAlign.left,
-                backgroundColor: ColorUtils.string2Color('#ffffff'),
-                maxLines: 1,
-                isFontMedium: true,
-              ),
-            ),
+         Expanded(
+            child: Row(
+              children: [
+                Expanded(
+                  child: Container(
+                    // height: 65.5,
+                    // color: Colors.blue,
+                    child: MyTextView(
+                      "What’s on your mind?",
+                      textColor: ColorUtils.string2Color('#000000'),
+                      fontSize: 15,
+                      marginLeft: 15,
+                      alignment: Alignment.centerLeft,
+                      textAlign: TextAlign.left,
+                      backgroundColor: ColorUtils.string2Color('#ffffff'),
+                      maxLines: 1,
+                      isFontMedium: true,
+                    ),
+                  ),
+                ),
+                const MyAssetImage(
+                  Assets.communityCamera,
+                  width: 21,
+                  height: 16.5,
+                ),
+              ],
+            ).onTap((){
+              vm.handlerGotoPost(context);
+            }),
           ),
-          const MyAssetImage(
-            Assets.communityCamera,
-            width: 21,
-            height: 16.5,
-          ).onTap(() {
-            // 点击 发布的按钮
-            vm.handlerGotoPost();
-          }),
         ],
       ),
     );
   }
 
   Widget _buildNewsItem(BuildContext context, WidgetRef ref, item, vm){
-    print("1111111${item}");
     return Container(
       width: double.infinity,
       // padding: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
@@ -167,8 +175,49 @@ class NewsfeedPage extends HookConsumerWidget {
             //     child: _buildNesFeedList(context, ref, vm),
             //   ),
             // )
-            Expanded(
-              child: _buildNesFeedList(context, ref, vm),
+            NotificationListener <ScrollNotification>(
+              onNotification: (ScrollNotification notification) {
+                // 检查当前页面是否是可见的
+                bool isDownOrUp = notification.metrics.axis == Axis.vertical;
+                if (notification is UserScrollNotification) {
+                  // 检查滚动方向
+                  switch (notification.direction) {
+                    case ScrollDirection.forward:
+                      print('Scrolling down');
+                      break;
+                    case ScrollDirection.reverse:
+                      print('Scrolling up');
+                      break;
+                    case ScrollDirection.idle:
+                      print('Scrolling stopped');
+                      break;
+                  }
+                } else if (notification is ScrollUpdateNotification) {
+                  // 检查滚动位置变化
+                  double currentScrollPosition = notification.metrics.pixels;
+                  double maxScrollExtent = notification.metrics.maxScrollExtent;
+
+                  // 判断是否满足某个条件
+                  if (currentScrollPosition > 0 && currentScrollPosition < maxScrollExtent) {
+                    print('Current scroll position: $currentScrollPosition');
+                    // 在这里添加你的条件判断逻辑
+                  }
+
+                  // 只有当上下滚动时才拦截通知
+                  if (notification.metrics.axis == Axis.vertical) {
+                    final tabsRouter = ref.watch(communityVmProvider).tabsRouter;
+                    final curUseTag = ref.watch(communityVmProvider).useTag;
+                    if(curUseTag != 0 ){
+                      // 非当前 页面都阻止滚动
+                      return true; // 返回 true 表示已处理通知
+                    }
+                  }
+                }
+                return false; // 返回 false 表示不拦截通知
+              },
+              child: Expanded(
+                child: _buildNesFeedList(context, ref, vm),
+              ),
             )
           ],
       ),

+ 155 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_page.dart

@@ -0,0 +1,155 @@
+import 'package:cpt_community/router/page/community_page_router.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_text_field.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:widgets/my_button.dart';
+
+import 'newsfeed_post_vm.dart';
+
+@RoutePage()
+class NewsfeedPostPage extends HookConsumerWidget {
+  const NewsfeedPostPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const NewsfeedPostPageRoute());
+    } else {
+      appRouter.push(const NewsfeedPostPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    // final viewModel = ref.watch(newsfeedPostVmProvider.notifier);
+    final state = ref.watch(newsfeedPostVmProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "Create Post",
+        backgroundColor: context.appColors.whiteBG,
+      ),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: Column(
+        children: [
+          Expanded(
+            child: SingleChildScrollView(
+              scrollDirection: Axis.vertical,
+              physics: const BouncingScrollPhysics(),
+              clipBehavior: Clip.none,
+              child: Column(
+                children: [
+                  Container(
+                    width: double.infinity,
+                    height: 200,
+                    decoration: BoxDecoration(
+                      border: Border.all(
+                        color: Colors.grey,
+                        width: 1
+                      ),
+                      borderRadius: BorderRadius.circular(10),
+                      boxShadow: [
+                        BoxShadow(
+                          color: Colors.grey.withOpacity(0.5),
+                          spreadRadius: 1,
+                          blurRadius: 1,
+                          offset: const Offset(0, 3), // changes position of shadow
+                        ),
+                      ]
+                    ),
+                    child: _buildInputLayout(
+                      context,
+                      state,
+                      'mind'
+                    ),
+                  ).marginOnly(left:15, right:15, top: 20, bottom: 20),
+                  Container(
+                    width: double.infinity,
+                    height: 200,
+                    color: Colors.grey,
+                  ),
+                ]
+              )
+            )
+          ),
+          Container(
+            child: Row(
+                children: [
+                  Expanded(
+                    child: MyButton(
+                      text: "Add Card",
+                      backgroundColor: context.appColors.textPrimary,
+                      textColor: Colors.white,
+                      fontWeight: FontWeight.w500,
+                      fontSize: 16,
+                      onPressed: (){
+                        // Navigator.pop(context);
+                      },
+                    ),
+                  ),
+                ]
+            ),
+          )
+        ]
+      ),
+    );
+  }
+
+
+  /// 输入框
+  Widget _buildInputLayout(
+      BuildContext context,
+      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,
+      ),
+    );
+  }
+}

+ 8 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_page_state.dart

@@ -0,0 +1,8 @@
+class NewsfeedPostPageState {
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  const NewsfeedPostPageState({
+    required this.formData,
+  });
+}

+ 47 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_vm.dart

@@ -0,0 +1,47 @@
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/path/router_path.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:auto_route/auto_route.dart';
+
+
+import 'newsfeed_post_page_state.dart';
+
+part 'newsfeed_post_vm.g.dart';
+
+@riverpod
+class NewsfeedPostVm extends _$NewsfeedPostVm {
+
+  NewsfeedPostPageState initState() {
+    return NewsfeedPostPageState(
+      formData: {
+        'mind': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': 'What\'s on your mind?',
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'images': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': '',
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+      },
+    );
+  }
+  @override
+  NewsfeedPostPageState build(){
+    // 初始化状态
+    NewsfeedPostPageState state = initState();
+    return state;
+  }
+
+
+}

+ 26 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_post/newsfeed_post_vm.g.dart

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

+ 6 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_state.dart

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
 import 'package:shared/utils/color_utils.dart';
 
 class NewsfeedState {
+  int? useTag = 0;
   int? curPage;
   int? pageSize;
   int? filterCount;
@@ -13,6 +14,7 @@ class NewsfeedState {
 
 
   NewsfeedState copyWith({
+    int? useTag,
     int? curPage,
     int? pageSize,
     int? filterCount,
@@ -21,6 +23,7 @@ class NewsfeedState {
     List? list,
   }) {
     return NewsfeedState(
+      useTag: useTag ?? this.useTag,
       curPage: curPage ?? this.curPage,
       pageSize: pageSize ?? this.pageSize,
       filterCount: filterCount ?? this.filterCount,
@@ -32,6 +35,7 @@ class NewsfeedState {
 
   Map<String, dynamic> toMap() {
     return {
+      'useTag': this.useTag,
       'curPage': this.curPage,
       'pageSize': this.pageSize,
       'filterCount': this.filterCount,
@@ -43,6 +47,7 @@ class NewsfeedState {
 
   factory NewsfeedState.fromMap(Map<String, dynamic> map) {
     return NewsfeedState(
+      useTag: map['useTag'] as int,
       curPage: map['curPage'] as int,
       pageSize: map['pageSize'] as int,
       filterCount: map['filterCount'] as int,
@@ -53,6 +58,7 @@ class NewsfeedState {
   }
 
   NewsfeedState({
+    this.useTag,
     this.curPage,
     this.pageSize,
     this.filterCount,

+ 111 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_tabs.dart

@@ -0,0 +1,111 @@
+import 'package:cpt_community/modules/newsfeed/newsfeed_vm.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
+
+import '../community/community_vm.dart';
+import '../garagesale/garagesale_vm.dart';
+
+class NewsfeedTabs extends HookConsumerWidget {
+  List tabsList;
+  Widget? Function(BuildContext)? tabItemBuilder;
+  VoidCallback? onClickAction;
+  NewsfeedTabs({
+    Key? key,
+    required this.tabsList,
+    this.onClickAction,
+    this.tabItemBuilder
+  }) : super(key: key);
+
+  Widget _buildTabItem(BuildContext context, WidgetRef ref, vm, item, index) {
+    // 监听 activeIndex 的变化
+    final activeIndex = ref.watch(newsfeedVmProvider.select((state) => state.activeIndex));
+
+
+    return Container(
+      width: MediaQuery.of(context).size.width / vm.state.tabsList.length - 30,
+      height: 43,
+      padding: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
+      decoration: index==activeIndex? BoxDecoration(
+        color: index==activeIndex? context.appColors.btnBgDefault: ColorUtils.string2Color("#F2F3F6"),
+        borderRadius: BorderRadius.circular(20),
+        boxShadow: [
+          BoxShadow(
+            color: Colors.grey.withOpacity(0.5),
+            spreadRadius: 1,
+            blurRadius: 5,
+            offset: const Offset(0, 2), // changes position of shadow
+          ),
+        ],
+      ): null,
+      child: Row(
+        children: [
+          Expanded(
+            child: Container(
+              alignment: Alignment.center,
+              child: MyTextView(
+                item['title'],
+                fontSize: 16,
+                textAlign: TextAlign.center,
+                isFontMedium: true,
+                textColor: index == activeIndex ? Colors.white :ColorUtils.string2Color("#000000"),
+              ),
+            ),
+          ),
+        ],
+      ),
+    ).onTap((){
+      vm.handlerClickTab(index, item);
+    });
+  }
+
+  List<Widget> _buildTabs(BuildContext context, WidgetRef ref, vm){
+
+    int currentUseTag = ref.watch(newsfeedVmProvider.select((state) => state.useTag!));
+
+    List tabsList = ref.read(newsfeedVmProvider).tabsList;
+
+    int tabsLength = tabsList.length;
+
+    return List.generate(tabsLength, (index) {
+      return _buildTabItem(context, ref, vm, tabsList[index], index);
+    });
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(newsfeedVmProvider.notifier);
+    // 使用useEffect钩子
+    useEffect(() {
+      print('副作用函数执行');
+      // 这里是副作用逻辑
+      // vm.initPropData(tabsList, tabItemBuilder, onClickAction);
+      // 返回清理函数
+      return () {
+        print('清理函数执行');
+      };
+    }, []); // 空依赖列表意味着这个副作用只在组件挂载时执行一次
+
+    return SingleChildScrollView(
+      scrollDirection: Axis.horizontal,
+      physics: const BouncingScrollPhysics(),
+      clipBehavior: Clip.none,
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: _buildTabs(context, ref, vm),
+      ).constrained(
+          maxWidth:  MediaQuery.of(context).size.width
+      ),
+    );
+  }
+}

+ 62 - 2
packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.dart

@@ -3,8 +3,11 @@ import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
+import 'package:router/path/router_path.dart';
 import 'package:shared/utils/color_utils.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:auto_route/auto_route.dart';
 
 import 'newsfeed_state.dart';
 import 'newsfeed_repository.dart';
@@ -16,11 +19,13 @@ class NewsfeedVm extends _$NewsfeedVm {
   late NewsfeedRepository newsfeedRepository;
   NewsfeedState initState() {
     return NewsfeedState(
+      useTag: 0,
       activeIndex: 0,
       tabsList: [
         {
           'title': 'News',
           'icon': null,
+          'active': true,
           'activeTitleColor': Colors.white,
           'activeTitleFontSize': 16,
           'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
@@ -28,6 +33,7 @@ class NewsfeedVm extends _$NewsfeedVm {
         {
           'title': 'Following',
           'icon': null,
+          'active': false,
           'activeTitleColor': Colors.white,
           'activeTitleFontSize': 16,
           'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
@@ -74,6 +80,50 @@ class NewsfeedVm extends _$NewsfeedVm {
             'isLike': false,
             'likeno': 12
           },
+          {
+            'id':4,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':5,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':6,
+            'avator': Assets.communityCamera,
+            'title': 'Fsjfkds  dfsk',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
+          {
+            'id':7,
+            'avator': Assets.communityCamera,
+            'title': '放大发大水',
+            'isFollow': false,
+            'content': 'She said YES and our lives changed.Thank you all for coming to my propose today.We hope everyone can ……[More]',
+            'imageUrls': [],
+            'time': 'June 17,2016 at 7:23 p.m.',
+            'isLike': false,
+            'likeno': 12
+          },
       ]
     );
   }
@@ -88,7 +138,7 @@ class NewsfeedVm extends _$NewsfeedVm {
 
   // 上拉加载
   Future onLoadData() async {
-    Log.d("----property_news_vm-----initListData");
+    Log.d("----newsfeed_vm-----initListData");
     // await Future.delayed(const Duration(seconds: 2));
     // if(state.list.length >= state.filterCount){
     //   return;
@@ -142,7 +192,17 @@ class NewsfeedVm extends _$NewsfeedVm {
 
 
   // 点击发布的按钮 跳转到发布的页面
-  void handlerGotoPost(){
+  void handlerGotoPost(context){
+    // ComponentServiceManager().communityService.startCommunityPage();
+
+    AutoRouter.of(context).pushNamed(RouterPath.newsFeedPost);
+  }
+
+  // 点击tab
+  void handlerClickTab(int index, item){
+    state = state.copyWith(activeIndex: index);
+    print("切换后新的 sate, ${state.tabsList}");
 
+    // ref.invalidate(customTabsVmProvider);
   }
 }

+ 1 - 1
packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.g.dart

@@ -6,7 +6,7 @@ part of 'newsfeed_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$newsfeedVmHash() => r'0d147c845251f1b8031020ef5dc25250e56192ab';
+String _$newsfeedVmHash() => r'8913ddbbe012f28caa65fbc8fdd824a8b818d4c6';
 
 /// See also [NewsfeedVm].
 @ProviderFor(NewsfeedVm)

+ 37 - 1
packages/cpt_community/lib/router/page/community_page_router.dart

@@ -4,8 +4,14 @@ import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 
 import '../../modules/community/community_page.dart';
+import '../../modules/garagesale/garagesale_detail/garagesale_detail_page.dart';
 import '../../modules/newsfeed/newsfeed_page.dart';
 import '../../modules/garagesale/garagesale_page.dart';
+import '../../modules/newsfeed/newsfeed_post/newsfeed_post_page.dart';
+import '../../modules/newsfeed/newsfeed_detail/newsfeed_detail_page.dart';
+import '../../modules/newsfeed/newsfeed_myposts/newsfeed_myposts_page.dart';
+import '../../modules/garagesale/garagesale_myposts/garagesale_myposts_page.dart';
+import '../../modules/garagesale/garagesale_post/garagesale_post_page.dart';
 
 part 'community_page_router.gr.dart';
 
@@ -32,7 +38,37 @@ class CommunityPageRouter extends _$CommunityPageRouter {
             path: RouterPath.garageSale,
             transitionsBuilder: applySlideTransition,
           ),
-        ]
+        ],
+    ),
+    CustomRoute(
+      page: NewsfeedPostPageRoute.page,
+      path: RouterPath.newsFeedPost,
+      transitionsBuilder: applySlideTransition,
+    ),
+    CustomRoute(
+      page: NewsfeedDetailPageRoute.page,
+      path: RouterPath.newsFeedDetail,
+      transitionsBuilder: applySlideTransition,
+    ),
+    CustomRoute(
+      page: NewsfeedMypostsPageRoute.page,
+      path: RouterPath.newsFeedMyPosts,
+      transitionsBuilder: applySlideTransition,
+    ),
+    CustomRoute(
+      page: GaragesalePostPageRoute.page,
+      path: RouterPath.garageSalePost,
+      transitionsBuilder: applySlideTransition,
+    ),
+    CustomRoute(
+      page: GaragesaleDetailPageRoute.page,
+      path: RouterPath.garageSaleDetail,
+      transitionsBuilder: applySlideTransition,
+    ),
+    CustomRoute(
+      page: GaragesaleMypostsPageRoute.page,
+      path: RouterPath.garageSaleMyPosts,
+      transitionsBuilder: applySlideTransition,
     ),
   ];
 }

+ 120 - 0
packages/cpt_community/lib/router/page/community_page_router.gr.dart

@@ -21,18 +21,54 @@ abstract class _$CommunityPageRouter extends RootStackRouter {
         child: const CommunityPage(),
       );
     },
+    GaragesaleDetailPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const GaragesaleDetailPage(),
+      );
+    },
+    GaragesaleMypostsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const GaragesaleMypostsPage(),
+      );
+    },
     GaragesalePageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const GaragesalePage(),
       );
     },
+    GaragesalePostPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const GaragesalePostPage(),
+      );
+    },
+    NewsfeedDetailPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const NewsfeedDetailPage(),
+      );
+    },
+    NewsfeedMypostsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const NewsfeedMypostsPage(),
+      );
+    },
     NewsfeedPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const NewsfeedPage(),
       );
     },
+    NewsfeedPostPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const NewsfeedPostPage(),
+      );
+    },
   };
 }
 
@@ -51,6 +87,34 @@ class CommunityPageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [GaragesaleDetailPage]
+class GaragesaleDetailPageRoute extends PageRouteInfo<void> {
+  const GaragesaleDetailPageRoute({List<PageRouteInfo>? children})
+      : super(
+          GaragesaleDetailPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'GaragesaleDetailPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [GaragesaleMypostsPage]
+class GaragesaleMypostsPageRoute extends PageRouteInfo<void> {
+  const GaragesaleMypostsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          GaragesaleMypostsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'GaragesaleMypostsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [GaragesalePage]
 class GaragesalePageRoute extends PageRouteInfo<void> {
   const GaragesalePageRoute({List<PageRouteInfo>? children})
@@ -65,6 +129,48 @@ class GaragesalePageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [GaragesalePostPage]
+class GaragesalePostPageRoute extends PageRouteInfo<void> {
+  const GaragesalePostPageRoute({List<PageRouteInfo>? children})
+      : super(
+          GaragesalePostPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'GaragesalePostPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [NewsfeedDetailPage]
+class NewsfeedDetailPageRoute extends PageRouteInfo<void> {
+  const NewsfeedDetailPageRoute({List<PageRouteInfo>? children})
+      : super(
+          NewsfeedDetailPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'NewsfeedDetailPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [NewsfeedMypostsPage]
+class NewsfeedMypostsPageRoute extends PageRouteInfo<void> {
+  const NewsfeedMypostsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          NewsfeedMypostsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'NewsfeedMypostsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [NewsfeedPage]
 class NewsfeedPageRoute extends PageRouteInfo<void> {
   const NewsfeedPageRoute({List<PageRouteInfo>? children})
@@ -77,3 +183,17 @@ class NewsfeedPageRoute extends PageRouteInfo<void> {
 
   static const PageInfo<void> page = PageInfo<void>(name);
 }
+
+/// generated route for
+/// [NewsfeedPostPage]
+class NewsfeedPostPageRoute extends PageRouteInfo<void> {
+  const NewsfeedPostPageRoute({List<PageRouteInfo>? children})
+      : super(
+          NewsfeedPostPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'NewsfeedPostPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}

+ 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,
                 ))

+ 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,
                 ))

+ 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,

+ 3 - 3
packages/cpt_main/lib/modules/me/me_view_model.dart

@@ -11,12 +11,12 @@ class MeViewModel extends _$MeViewModel {
 
   //去我的房产页面
   void gotoMyEstatePage() {
-    ToastEngine.show("去我的房产页面");
+    ComponentServiceManager().profileService.startMyEstatePage();
   }
 
   //去我的家庭成员页面
   void gotoMyHouseholdPage() {
-    ToastEngine.show("去我的家庭成员页面");
+    ComponentServiceManager().profileService.startMyHouseHoldPage();
   }
 
   //去我的发布页面
@@ -41,6 +41,6 @@ class MeViewModel extends _$MeViewModel {
 
   //编辑附加信息
   void gotoEditProfilePage() {
-    ToastEngine.show("编辑附加信息");
+    ComponentServiceManager().profileService.startEditProfilePage();
   }
 }

+ 10 - 19
packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart

@@ -7,6 +7,7 @@ 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';
@@ -15,6 +16,7 @@ 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';
@@ -38,7 +40,7 @@ class VisitorRegisterPage extends HookConsumerWidget {
     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,
@@ -145,24 +147,13 @@ class VisitorRegisterPage extends HookConsumerWidget {
                 marginTop: 14.5,
                 isFontMedium: true,
               ),
-              // 表单
-              _buildInputLayout(
-                context,
-                state,
-                "access_date",
-                marginTop: 15,
-                enable: false,
-                textInputType: TextInputType.text,
-                textInputAction: TextInputAction.next,
-                showRightIcon: true,
-                rightWidget: const MyAssetImage(Assets.mainVisitorRegisterDate, width: 21, height: 20).paddingOnly(top: 13, bottom: 13),
-                onSubmit: (formKey, value) {
-                  state.formData[formKey]!['focusNode'].unfocus();
-                  FocusScope.of(context).requestFocus(state.formData['note']!['focusNode']);
-                },
-              ).onTap(() {
-                viewModel.pickAccessDate();
-              }),
+              // 选择器
+              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(

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

@@ -46,12 +46,6 @@ class VisitorRegisterState {
                 'focusNode': FocusNode(),
                 'obsecure': false,
               },
-              'access_date': {
-                'value': '',
-                'controller': TextEditingController(),
-                'focusNode': FocusNode(),
-                'obsecure': false,
-              },
               'note': {
                 'value': '',
                 'controller': TextEditingController(),

+ 1 - 3
packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart

@@ -76,7 +76,7 @@ class VisitorRegisterViewModel extends _$VisitorRegisterViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
+    ToastEngine.show('准备执行请求 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
 
     //去首页
     MainPage.startInstance();
@@ -89,8 +89,6 @@ class VisitorRegisterViewModel extends _$VisitorRegisterViewModel {
       mode: CupertinoDatePickerMode.date,
       onDateTimeChanged: (date) {
        state = state.copyWith(accessDate: date);
-       final TextEditingController accessDateController = state.formData['access_date']!['controller'];
-       accessDateController.text = DateTimeUtils.formatDate(date,format: 'dd MMM yyyy');
       },
       title: S.current.access_date,
     );

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

@@ -7,7 +7,7 @@ part of 'visitor_register_view_model.dart';
 // **************************************************************************
 
 String _$visitorRegisterViewModelHash() =>
-    r'efcd5105243eb7a8ec68d0ff5d428e7eb72fded0';
+    r'7ce971f03307d867b5069f6abff1a28ac4eea1eb';
 
 /// See also [VisitorRegisterViewModel].
 @ProviderFor(VisitorRegisterViewModel)

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

@@ -23,6 +23,9 @@ 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';
 
@@ -75,5 +78,8 @@ class MainPageRouter extends _$MainPageRouter {
         ),
         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),
       ];
 }

+ 60 - 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,
@@ -139,6 +157,48 @@ abstract class _$MainPageRouter extends RootStackRouter {
 }
 
 /// 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})

+ 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");
+    });
+  }
 }

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

@@ -7,12 +7,12 @@ part of 'profile_edit_view_model.dart';
 // **************************************************************************
 
 String _$profileEditViewModelHash() =>
-    r'acfbe7986503c631d7107a9309c85e768b1067f2';
+    r'077ce4db8df95158eed8dfb5a207c1f472271d13';
 
 /// See also [ProfileEditViewModel].
 @ProviderFor(ProfileEditViewModel)
-final profileEditViewModelProvider =
-    AutoDisposeNotifierProvider<ProfileEditViewModel, void>.internal(
+final profileEditViewModelProvider = AutoDisposeNotifierProvider<
+    ProfileEditViewModel, ProfileEditState>.internal(
   ProfileEditViewModel.new,
   name: r'profileEditViewModelProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -22,6 +22,6 @@ final profileEditViewModelProvider =
   allTransitiveDependencies: null,
 );
 
-typedef _$ProfileEditViewModel = AutoDisposeNotifier<void>;
+typedef _$ProfileEditViewModel = AutoDisposeNotifier<ProfileEditState>;
 // 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

+ 1 - 1
packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'reset_password_view_model.dart';
 // **************************************************************************
 
 String _$resetPasswordViewModelHash() =>
-    r'4b6b7ea5f180d679389a10da92758d39ea9f86e3';
+    r'909d66fe8a4977520cc6d2d5d0607e3d979a74b4';
 
 /// See also [ResetPasswordViewModel].
 @ProviderFor(ResetPasswordViewModel)

+ 1 - 1
packages/cpt_profile/lib/modules/setting/setting_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'setting_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$settingViewModelHash() => r'e008ce2120bd069243f13ad1502eba8992950a63';
+String _$settingViewModelHash() => r'14220f4fbd357cfd7f80abccc4db5ec17814c539';
 
 /// See also [SettingViewModel].
 @ProviderFor(SettingViewModel)

+ 8 - 8
packages/cpt_profile/lib/router/component/profile_component_service_impl.dart

@@ -1,6 +1,8 @@
 /*
  * Profile 组件的组件路由
  */
+import 'package:cpt_profile/modules/my_estate/my_estate_page.dart';
+import 'package:cpt_profile/modules/my_household/my_household_page.dart';
 import 'package:cpt_profile/modules/setting/setting_page.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:router/componentRouter/profile_service.dart';
@@ -14,16 +16,14 @@ class ProfileComponentServiceImpl extends ProfileService {
   }
 
   @override
-  void startMyEstatePage({BuildContext? context}) {}
-
-  @override
-  void startMyFollowPage({BuildContext? context}) {}
-
-  @override
-  void startMyHouseHoldPage({BuildContext? context}) {}
+  void startMyEstatePage({BuildContext? context}) {
+    MyEstatePage.startInstance(context: context);
+  }
 
   @override
-  void startMyPostPage({BuildContext? context}) {}
+  void startMyHouseHoldPage({BuildContext? context}) {
+    MyHouseholdPage.startInstance(context: context);
+  }
 
   @override
   void startSettingPage({BuildContext? context}) {

+ 4 - 0
packages/cpt_profile/lib/router/page/profile_page_router.dart

@@ -7,6 +7,8 @@ import '../../modules/profile_edit/Profile_edit_page.dart';
 import '../../modules/setting/setting_page.dart';
 import '../../modules/change_mobile/change_mobile_page.dart';
 import '../../modules/reset_password/reset_password_page.dart';
+import '../../modules/my_estate/my_estate_page.dart';
+import '../../modules/my_household/my_household_page.dart';
 
 
 part 'profile_page_router.gr.dart';
@@ -23,5 +25,7 @@ class ProfilePageRouter extends _$ProfilePageRouter {
     CustomRoute(page: SettingPageRoute.page, path: RouterPath.settings, transitionsBuilder: applySlideTransition),
     CustomRoute(page: ChangeMobilePageRoute.page, path: RouterPath.settingsChangeMobile, transitionsBuilder: applySlideTransition),
     CustomRoute(page: ResetPasswordPageRoute.page, path: RouterPath.settingsResetPassword, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: MyEstatePageRoute.page, path: RouterPath.profileEstate, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: MyHouseholdPageRoute.page, path: RouterPath.profileHousehold, transitionsBuilder: applySlideTransition),
   ];
 }

+ 40 - 0
packages/cpt_profile/lib/router/page/profile_page_router.gr.dart

@@ -21,6 +21,18 @@ abstract class _$ProfilePageRouter extends RootStackRouter {
         child: const ChangeMobilePage(),
       );
     },
+    MyEstatePageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const MyEstatePage(),
+      );
+    },
+    MyHouseholdPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const MyHouseholdPage(),
+      );
+    },
     ProfileEditPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -57,6 +69,34 @@ class ChangeMobilePageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [MyEstatePage]
+class MyEstatePageRoute extends PageRouteInfo<void> {
+  const MyEstatePageRoute({List<PageRouteInfo>? children})
+      : super(
+          MyEstatePageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'MyEstatePageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [MyHouseholdPage]
+class MyHouseholdPageRoute extends PageRouteInfo<void> {
+  const MyHouseholdPageRoute({List<PageRouteInfo>? children})
+      : super(
+          MyHouseholdPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'MyHouseholdPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [ProfileEditPage]
 class ProfileEditPageRoute extends PageRouteInfo<void> {
   const ProfileEditPageRoute({List<PageRouteInfo>? children})

+ 3 - 0
packages/cpt_property/lib/modules/ioan/property_ioan_page.dart

@@ -368,6 +368,9 @@ class PropertyIoanPage extends HookConsumerWidget {
         children: [
           Expanded(
             child: SingleChildScrollView(
+              scrollDirection: Axis.vertical,
+              physics: const BouncingScrollPhysics(),
+              clipBehavior: Clip.none,
               child: Padding(
                   padding: const EdgeInsets.only(left: 15,right: 15,top: 15),
                   child: _buildCotentBox(context, ref, _vm),

+ 1 - 0
packages/cs_plugin_platform/lib/engine/image/image_nine_grid.dart

@@ -9,6 +9,7 @@ import 'package:widgets/my_text_view.dart';
 import 'image_preview.dart';
 import 'package:cs_resources/generated/l10n.dart';
 
+/// 九宫格的图片选择与图片展示
 class ImageNineGrid extends StatefulWidget {
   final bool isSelectEnable; // 是否能选择
   final List<String> initialImages; // 初始化图片集合

+ 2 - 1
packages/cs_plugin_platform/lib/platform_export.dart

@@ -1,3 +1,4 @@
 export 'package:dio/dio.dart';
 export 'package:permission_handler/permission_handler.dart';
-export 'engine/image/image_nine_grid.dart';
+export 'engine/image/image_nine_grid.dart';
+export 'engine/media/image_picker_utils.dart';

BIN
packages/cs_resources/assets/profile/edit_dialog_delete.webp


BIN
packages/cs_resources/assets/profile/edit_dialog_upload.webp


BIN
packages/cs_resources/assets/profile/edit_profile_add.webp


BIN
packages/cs_resources/assets/profile/edit_profile_avatar_bottom.webp


BIN
packages/cs_resources/assets/profile/edit_profile_avatar_default.webp


BIN
packages/cs_resources/assets/profile/edit_xu_line.webp


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

@@ -102,6 +102,12 @@ class Assets {
   static const String noticeBoardAnnouncementIcon = 'assets/notice_board/announcement_icon.png';
   static const String noticeBoardDocumentsIcon = 'assets/notice_board/documents_icon.png';
   static const String noticeBoardEventIcon = 'assets/notice_board/event_icon.png';
+  static const String profileEditDialogDelete = 'assets/profile/edit_dialog_delete.webp';
+  static const String profileEditDialogUpload = 'assets/profile/edit_dialog_upload.webp';
+  static const String profileEditProfileAdd = 'assets/profile/edit_profile_add.webp';
+  static const String profileEditProfileAvatarBottom = 'assets/profile/edit_profile_avatar_bottom.webp';
+  static const String profileEditProfileAvatarDefault = 'assets/profile/edit_profile_avatar_default.webp';
+  static const String profileEditXuLine = 'assets/profile/edit_xu_line.webp';
   static const String propertyAdvicePic = 'assets/property/advice_pic.webp';
   static const String propertyApproval = 'assets/property/approval.webp';
   static const String propertyCollection = 'assets/property/collection.webp';

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

@@ -26,13 +26,13 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images": MessageLookupByLibrary.simpleMessage(
-            "(Up to 10 images can be uploaded)"),
         "access_date": MessageLookupByLibrary.simpleMessage("Access Date"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "Are you sure you want to deactivate your account? You will not be able to login into the app once you proceed with the request."),
         "account_deactivation":
             MessageLookupByLibrary.simpleMessage("Account Deactivation"),
+        "active": MessageLookupByLibrary.simpleMessage("ACTIVE"),
+        "add": MessageLookupByLibrary.simpleMessage("Add"),
         "administrator_reply":
             MessageLookupByLibrary.simpleMessage("Administrator Reply"),
         "agree_to": MessageLookupByLibrary.simpleMessage("Agree to"),
@@ -65,6 +65,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Describe Your FeedBack"),
         "did_not_receive":
             MessageLookupByLibrary.simpleMessage("Did Not Receive?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("Edit Profile"),
         "email": MessageLookupByLibrary.simpleMessage("Email"),
         "enable_notification":
             MessageLookupByLibrary.simpleMessage("Enable Notification"),
@@ -75,6 +76,8 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Estate or Building Name?"),
         "facility": MessageLookupByLibrary.simpleMessage("Facility"),
         "feedback": MessageLookupByLibrary.simpleMessage("FeedBack"),
+        "feedback_details":
+            MessageLookupByLibrary.simpleMessage("FeedBack Details"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage(
             "Help us keep your estate beautiful"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
@@ -124,6 +127,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "nric_fin": MessageLookupByLibrary.simpleMessage("NRIC/FIN"),
         "old_mobile_phone":
             MessageLookupByLibrary.simpleMessage("Old Mobile Phone"),
+        "or": MessageLookupByLibrary.simpleMessage("or"),
         "other": MessageLookupByLibrary.simpleMessage("Other"),
         "owner": MessageLookupByLibrary.simpleMessage("Owner"),
         "owner_or_tenant":
@@ -155,6 +159,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "published_successfully":
             MessageLookupByLibrary.simpleMessage("Published Successfully"),
         "rate_us": MessageLookupByLibrary.simpleMessage("Rate Us"),
+        "remove": MessageLookupByLibrary.simpleMessage("Remove"),
         "resend_code": MessageLookupByLibrary.simpleMessage("Resend Code"),
         "reset_password":
             MessageLookupByLibrary.simpleMessage("Reset Password"),
@@ -191,7 +196,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("Tries Left"),
         "type_here": MessageLookupByLibrary.simpleMessage("Type Here"),
         "unit_number": MessageLookupByLibrary.simpleMessage("Unit Number"),
+        "up_to_max_images": MessageLookupByLibrary.simpleMessage(
+            "(Up to 10 images can be uploaded)"),
         "upload": MessageLookupByLibrary.simpleMessage("Upload"),
+        "upload_a_photo":
+            MessageLookupByLibrary.simpleMessage("Upload a Photo"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "The Management requires that you upload the following documents to verify your tenancy. You may redact sensitive financia information"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

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

@@ -26,12 +26,12 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images":
-            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "access_date": MessageLookupByLibrary.simpleMessage("访问日期"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "您确定要停用您的帐户吗?一旦您继续执行请求,您将无法登录应用程序。"),
         "account_deactivation": MessageLookupByLibrary.simpleMessage("删除账号"),
+        "active": MessageLookupByLibrary.simpleMessage("可用"),
+        "add": MessageLookupByLibrary.simpleMessage("添加"),
         "administrator_reply": MessageLookupByLibrary.simpleMessage("管理员回复"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "alert": MessageLookupByLibrary.simpleMessage("提示"),
@@ -56,6 +56,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "describe_your_feedback":
             MessageLookupByLibrary.simpleMessage("描述您的反馈"),
         "did_not_receive": MessageLookupByLibrary.simpleMessage("没有收到验证码?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("编辑个人信息"),
         "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "enable_notification": MessageLookupByLibrary.simpleMessage("允许通知"),
         "estate": MessageLookupByLibrary.simpleMessage("房产"),
@@ -65,6 +66,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("房产或建筑名称?"),
         "facility": MessageLookupByLibrary.simpleMessage("设施"),
         "feedback": MessageLookupByLibrary.simpleMessage("反馈"),
+        "feedback_details": MessageLookupByLibrary.simpleMessage("反馈详情"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage("帮助我们保持您的房产美丽"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
             "有些事情需要我们关注,或者如果你有一个很棒的建议,我们想听听你的意见!"),
@@ -105,6 +107,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "nric_fin": MessageLookupByLibrary.simpleMessage("身份证/签证"),
         "old_mobile_phone": MessageLookupByLibrary.simpleMessage("旧的手机号码"),
+        "or": MessageLookupByLibrary.simpleMessage("或者"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "owner": MessageLookupByLibrary.simpleMessage("业主"),
         "owner_or_tenant": MessageLookupByLibrary.simpleMessage("您是业主还是租户?"),
@@ -127,6 +130,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
+        "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "resend_code": MessageLookupByLibrary.simpleMessage("重新发送"),
         "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("奖励"),
@@ -156,7 +160,10 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("次尝试机会"),
         "type_here": MessageLookupByLibrary.simpleMessage("在此输入"),
         "unit_number": MessageLookupByLibrary.simpleMessage("单元"),
+        "up_to_max_images":
+            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "upload": MessageLookupByLibrary.simpleMessage("上传"),
+        "upload_a_photo": MessageLookupByLibrary.simpleMessage("上传照片"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "管理员要求您上传以下文件以验证您的租约。您可以编辑敏感的财务信息"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

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

@@ -26,12 +26,12 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images":
-            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "access_date": MessageLookupByLibrary.simpleMessage("访问日期"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "您确定要停用您的帐户吗?一旦您继续执行请求,您将无法登录应用程序。"),
         "account_deactivation": MessageLookupByLibrary.simpleMessage("删除账号"),
+        "active": MessageLookupByLibrary.simpleMessage("可用"),
+        "add": MessageLookupByLibrary.simpleMessage("添加"),
         "administrator_reply": MessageLookupByLibrary.simpleMessage("管理员回复"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "alert": MessageLookupByLibrary.simpleMessage("提示"),
@@ -56,6 +56,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "describe_your_feedback":
             MessageLookupByLibrary.simpleMessage("描述您的反馈"),
         "did_not_receive": MessageLookupByLibrary.simpleMessage("没有收到验证码?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("编辑个人信息"),
         "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "enable_notification": MessageLookupByLibrary.simpleMessage("允许通知"),
         "estate": MessageLookupByLibrary.simpleMessage("房产"),
@@ -65,6 +66,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("房产或建筑名称?"),
         "facility": MessageLookupByLibrary.simpleMessage("設施"),
         "feedback": MessageLookupByLibrary.simpleMessage("反馈"),
+        "feedback_details": MessageLookupByLibrary.simpleMessage("反馈详情"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage("帮助我们保持您的房产美丽"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
             "有些事情需要我们关注,或者如果你有一个很棒的建议,我们想听听你的意见!"),
@@ -105,6 +107,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "nric_fin": MessageLookupByLibrary.simpleMessage("身份证/签证"),
         "old_mobile_phone": MessageLookupByLibrary.simpleMessage("旧的手机号码"),
+        "or": MessageLookupByLibrary.simpleMessage("或者"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
         "password_format": MessageLookupByLibrary.simpleMessage("8位数字或字母"),
@@ -119,6 +122,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
+        "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "resend_code": MessageLookupByLibrary.simpleMessage("重新发送"),
         "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("獎勵"),
@@ -143,7 +147,10 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("次尝试机会"),
         "type_here": MessageLookupByLibrary.simpleMessage("在此输入"),
         "unit_number": MessageLookupByLibrary.simpleMessage("单元"),
+        "up_to_max_images":
+            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "upload": MessageLookupByLibrary.simpleMessage("上传"),
+        "upload_a_photo": MessageLookupByLibrary.simpleMessage("上传照片"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "管理员要求您上传以下文件以验证您的租约。您可以编辑敏感的财务信息"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

+ 72 - 2
packages/cs_resources/lib/generated/l10n.dart

@@ -1321,10 +1321,10 @@ class S {
   }
 
   /// `(Up to 10 images can be uploaded)`
-  String get Up_to_max_images {
+  String get up_to_max_images {
     return Intl.message(
       '(Up to 10 images can be uploaded)',
-      name: 'Up_to_max_images',
+      name: 'up_to_max_images',
       desc: '',
       args: [],
     );
@@ -1380,6 +1380,76 @@ class S {
     );
   }
 
+  /// `FeedBack Details`
+  String get feedback_details {
+    return Intl.message(
+      'FeedBack Details',
+      name: 'feedback_details',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Upload a Photo`
+  String get upload_a_photo {
+    return Intl.message(
+      'Upload a Photo',
+      name: 'upload_a_photo',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `or`
+  String get or {
+    return Intl.message(
+      'or',
+      name: 'or',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Edit Profile`
+  String get edit_profile {
+    return Intl.message(
+      'Edit Profile',
+      name: 'edit_profile',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `ACTIVE`
+  String get active {
+    return Intl.message(
+      'ACTIVE',
+      name: 'active',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Remove`
+  String get remove {
+    return Intl.message(
+      'Remove',
+      name: 'remove',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Add`
+  String get add {
+    return Intl.message(
+      'Add',
+      name: 'add',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Other`
   String get other {
     return Intl.message(

+ 8 - 1
packages/cs_resources/lib/l10n/intl_en.arb

@@ -126,11 +126,18 @@
   "describe_your_feedback": "Describe Your FeedBack",
   "upload_pictures": "Upload Pictures",
   "send_feedback": "Send FeedBack",
-  "Up_to_max_images": "(Up to 10 images can be uploaded)",
+  "up_to_max_images": "(Up to 10 images can be uploaded)",
   "published_successfully": "Published Successfully",
   "published_successful_txt": "Your feedback has been successfully sent! We will reply to you as soon as possible! thank you!",
   "back_home": "Back Home",
   "waiting_for_the_administrator": "Waiting for the administrator",
   "administrator_reply": "Administrator Reply",
+  "feedback_details": "FeedBack Details",
+  "upload_a_photo": "Upload a Photo",
+  "or": "or",
+  "edit_profile": "Edit Profile",
+  "active": "ACTIVE",
+  "remove": "Remove",
+  "add": "Add",
   "other": "Other"
 }

+ 8 - 1
packages/cs_resources/lib/l10n/intl_zh_CN.arb

@@ -126,11 +126,18 @@
   "describe_your_feedback": "描述您的反馈",
   "upload_pictures": "上传图片",
   "send_feedback": "发送反馈",
-  "Up_to_max_images": "(您最多可以上传10张图片)",
+  "up_to_max_images": "(您最多可以上传10张图片)",
   "published_successfully": "发布成功",
   "published_successful_txt": "您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!",
   "back_home": "返回首页",
   "waiting_for_the_administrator": "等待管理员回复",
   "administrator_reply": "管理员回复",
+  "feedback_details": "反馈详情",
+  "upload_a_photo": "上传照片",
+  "or": "或者",
+  "edit_profile": "编辑个人信息",
+  "active": "可用",
+  "remove": "移除",
+  "add": "添加",
   "other": "其他"
 }

+ 8 - 1
packages/cs_resources/lib/l10n/intl_zh_HK.arb

@@ -112,11 +112,18 @@
   "describe_your_feedback": "描述您的反馈",
   "upload_pictures": "上传图片",
   "send_feedback": "发送反馈",
-  "Up_to_max_images": "(您最多可以上传10张图片)",
+  "up_to_max_images": "(您最多可以上传10张图片)",
   "published_successfully": "发布成功",
   "published_successful_txt": "您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!",
   "back_home": "返回首页",
   "waiting_for_the_administrator": "等待管理员回复",
   "administrator_reply": "管理员回复",
+  "feedback_details": "反馈详情",
+  "upload_a_photo": "上传照片",
+  "or": "或者",
+  "edit_profile": "编辑个人信息",
+  "active": "可用",
+  "remove": "移除",
+  "add": "添加",
   "other": "其他"
 }

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

@@ -29,6 +29,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   static const _colorDFF0FF = Color(0xFFDFF0FF);
   static const _color1B61CA = Color(0X4D1B61CA);
   static const _color8B96BA = Color(0xFF8B96BA);
+  static const _colorB4C5FF = Color(0xFFB4C5FF);
 
   //暗色主题的一些自定义颜色值
   static const _darkBlackBg = Color(0xFF0F0F0F);
@@ -66,6 +67,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   final Color tabTextUnSelectedDefault; //Tab文本,未选中 亮色为黑色,黑暗模式为灰色
   final Color tabLightBlueShadow; //Tab的淡蓝色阴影
   final Color textLightPurple; //文本淡紫色
+  final Color avatarBg; //头像框的淡蓝色
 
   // 私有的构造函数
   const AppColorsTheme._internal({
@@ -96,6 +98,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
     required this.tabTextSelectedDefault,
     required this.tabTextUnSelectedDefault,
     required this.textLightPurple,
+    required this.avatarBg,
   });
 
   // 浅色主题工厂方法
@@ -128,6 +131,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabTextSelectedDefault: _colorPrimary,
       tabTextUnSelectedDefault: Colors.black,
       textLightPurple: _color8B96BA,
+      avatarBg: _colorB4C5FF,
     );
   }
 
@@ -161,6 +165,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabTextSelectedDefault: Colors.white,
       tabTextUnSelectedDefault: _darkBlackItemLightMost,
       textLightPurple: Colors.white,
+      avatarBg: _darkBlackItemLight,
     );
   }
 
@@ -203,6 +208,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabLightBlueShadow: Color.lerp(tabLightBlueShadow, other.tabLightBlueShadow, t)!,
       tabTextUnSelectedDefault: Color.lerp(tabTextUnSelectedDefault, other.tabTextUnSelectedDefault, t)!,
       textLightPurple: Color.lerp(textLightPurple, other.textLightPurple, t)!,
+      avatarBg: Color.lerp(avatarBg, other.avatarBg, t)!,
     );
   }
 }

+ 1 - 0
packages/cs_resources/pubspec.yaml

@@ -31,6 +31,7 @@ flutter:
     - assets/auth/
     - assets/community/
     - assets/main/
+    - assets/profile/
 
 
 flutter_intl:

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

@@ -8,10 +8,6 @@ abstract class ProfileService {
 
   void startEditProfilePage({BuildContext? context});
 
-  void startMyPostPage({BuildContext? context});
-
-  void startMyFollowPage({BuildContext? context});
-
   void startMyHouseHoldPage({BuildContext? context});
 
   void startMyEstatePage({BuildContext? context});

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

@@ -40,6 +40,12 @@ class RouterPath {
 
   //社区
   static const community = '/community';
+  static const newsFeedPost = '/newsfeed_post';
+  static const newsFeedDetail = '/newsfeed_detail';
+  static const newsFeedMyPosts = '/newsfeed_my_posts';
+  static const garageSalePost = '/garage_sale_post';
+  static const garageSaleDetail = '/garage_sale_detail';
+  static const garageSaleMyPosts = '/garage_sale_my_posts';
   static const newsFeed = 'community/news_feed';
   static const garageSale = 'community/garage_sale';
 

+ 64 - 0
packages/cs_widgets/lib/shatter/picker_container.dart

@@ -0,0 +1,64 @@
+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 PickerContainer extends StatelessWidget {
+  final bool enable;
+  final String? hint;
+  final String? content;
+  final Widget? rightWidget;
+  final double height;
+  final Color? bgColor;
+  final EdgeInsetsGeometry? margin;
+  final VoidCallback onClick;
+
+  const PickerContainer({
+    required this.onClick,
+    this.enable = true,
+    this.hint,
+    this.content,
+    this.margin,
+    this.rightWidget,
+    this.bgColor,
+    this.height = 55,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+        height: height,
+        margin: margin,
+        padding: const EdgeInsets.symmetric(horizontal: 15),
+        decoration: BoxDecoration(
+          color: context.appColors.authFiledBG,
+          borderRadius: const BorderRadius.all(Radius.circular(5)),
+        ),
+        child: Row(
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            MyTextView(
+              content ?? "",
+              hint: hint,
+              textColor: context.appColors.textBlack,
+              isFontMedium: true,
+              fontSize: 16,
+            ).expanded(),
+            rightWidget != null
+                ? rightWidget!
+                : const MyAssetImage(
+                    Assets.baseServiceTriangleDropDownIcon,
+                    width: 11.5,
+                    height: 6.5,
+                  ),
+          ],
+        )).onTap(() {
+      if (enable) {
+        onClick.call();
+      }
+    });
+  }
+}