ソースを参照

update community module

glglove 1 週間 前
コミット
3825756631
共有31 個のファイルを変更した849 個の追加94 個の削除を含む
  1. 1 1
      melos.yaml
  2. 91 0
      packages/cpt_community/lib/components/custom_tabs.dart
  3. 29 0
      packages/cpt_community/lib/components/custom_tabs_state.dart
  4. 52 0
      packages/cpt_community/lib/components/custom_tabs_vm.dart
  5. 25 0
      packages/cpt_community/lib/components/custom_tabs_vm.g.dart
  6. 104 0
      packages/cpt_community/lib/modules/community/community_page.dart
  7. 37 0
      packages/cpt_community/lib/modules/community/community_state.dart
  8. 55 0
      packages/cpt_community/lib/modules/community/community_vm.dart
  9. 25 0
      packages/cpt_community/lib/modules/community/community_vm.g.dart
  10. 0 34
      packages/cpt_community/lib/modules/community/page/community_page.dart
  11. 34 0
      packages/cpt_community/lib/modules/garagesale/garagesale_page.dart
  12. 0 0
      packages/cpt_community/lib/modules/garagesale/garagesale_repository.dart
  13. 0 0
      packages/cpt_community/lib/modules/garagesale/garagesale_state.dart
  14. 14 14
      packages/cpt_community/lib/modules/community/vm/community_view_model.dart
  15. 25 0
      packages/cpt_community/lib/modules/garagesale/garagesale_vm.g.dart
  16. 65 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_page.dart
  17. 0 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_repository.dart
  18. 23 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_state.dart
  19. 47 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.dart
  20. 25 0
      packages/cpt_community/lib/modules/newsfeed/newsfeed_vm.g.dart
  21. 1 1
      packages/cpt_community/lib/router/component/community_component_service.dart
  22. 20 3
      packages/cpt_community/lib/router/page/community_page_router.dart
  23. 41 1
      packages/cpt_community/lib/router/page/community_page_router.gr.dart
  24. 6 6
      packages/cpt_property/lib/modules/ioan/property_ioan_page.dart
  25. 71 0
      packages/cpt_property/lib/modules/ioan/property_ioan_repository.dart
  26. 13 11
      packages/cpt_community/lib/modules/community/vm/community_view_model.g.dart
  27. 17 0
      packages/cpt_property/lib/modules/ioan/property_ioan_state.dart
  28. 1 1
      packages/cpt_property/lib/modules/ioan/property_ioan_vm.g.dart
  29. 22 22
      packages/cpt_property/lib/modules/property/page/property_page.dart
  30. 3 0
      packages/cs_resources/lib/generated/assets.dart
  31. 2 0
      packages/cs_router/lib/path/router_path.dart

+ 1 - 1
melos.yaml

@@ -48,7 +48,7 @@ scripts:
     description: Run `dart run build_runner build` in auth module
 
   build_runner_community:
-    run: cd "$MELOS_ROOT_PATH/packages/cpt_community" && dart run build_runner build --delete-conflicting-outputs
+    run: cd "$MELOS_ROOT_PATH/packages/cpt_community" && flutter pub run build_runner build --delete-conflicting-outputs
     description: Run `dart run build_runner build` in community module
 
   build_runner_facility:

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

@@ -0,0 +1,91 @@
+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_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) {
+    int? activeIndex = ref.watch(customTabsVmProvider).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
+      ),
+    );
+  }
+}

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

@@ -0,0 +1,29 @@
+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,
+    );
+  }
+}

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

@@ -0,0 +1,52 @@
+
+import 'package:cpt_community/components/custom_tabs_state.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+
+part 'custom_tabs_vm.g.dart';
+
+@riverpod
+class CustomTabsVm extends _$CustomTabsVm {
+  CustomTabsState initState(tabsList, activeIndex,tabItemBuilder, onClickAction) {
+    CustomTabsState state = CustomTabsState(
+        tabsList: tabsList,
+        activeIndex:activeIndex,
+        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}");
+  }
+
+}
+

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

@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'custom_tabs_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$customTabsVmHash() => r'34989e04bef32871e5ada4fb3a4bfdd44f7fb17f';
+
+/// 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

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

@@ -0,0 +1,104 @@
+
+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(),
+                      )
+                    ],
+                  ),
+                )
+              ],
+            )
+        );
+    }
+}

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

@@ -0,0 +1,37 @@
+import 'package:cs_resources/generated/assets.dart';
+
+import '../garagesale/garagesale_page.dart';
+import '../newsfeed/newsfeed_page.dart';
+
+class CommunityVmState {
+  List<Map<String, dynamic>>? topSectionsData;
+  int? curIdx;
+
+  CommunityVmState({
+    List<Map<String, dynamic>>? topSectionsData,
+    this.curIdx = 0,
+  }) : topSectionsData = topSectionsData?? [
+    {
+      "title": "News Feed",
+      "icon": Assets.communityNesFeed,
+      "pageStartInstanceFn": NewsfeedPage.startInstance,
+      "page": const NewsfeedPage(),
+    },
+    {
+      "title": "Garage Sale",
+      "icon": Assets.communityGarageSale,
+      "pageStartInstanceFn": GaragesalePage.startInstance,
+      "page": const GaragesalePage(),
+    },
+  ];
+
+  CommunityVmState copyWith({
+    List<Map<String, dynamic>>? topSectionsData,
+    int? curIdx = 0,
+  }) {
+    return CommunityVmState(
+      topSectionsData: topSectionsData ?? this.topSectionsData,
+      curIdx: curIdx ?? 0,
+    );
+  }
+}

+ 55 - 0
packages/cpt_community/lib/modules/community/community_vm.dart

@@ -0,0 +1,55 @@
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+
+import 'community_state.dart';
+
+import '../garagesale/garagesale_page.dart';
+import '../newsfeed/newsfeed_page.dart';
+
+part 'community_vm.g.dart';
+
+@riverpod
+class CommunityVm extends _$CommunityVm {
+  get topSectionsData => state.topSectionsData;
+
+  CommunityVmState initState() {
+    return CommunityVmState();
+  }
+
+  @override
+  CommunityVmState build(){
+    final state = initState();
+    Log.d("--------------------------build---------------------");
+
+    // 初始时导航到子路由
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      switchPage(state.curIdx ?? 0, null, true);
+    });
+
+    return state;
+  }
+
+  // 页面切换
+  switchPage(int index,BuildContext? context, [bool? isFirstInitSwitch] ){
+    if(state.curIdx != index){
+      state = state.copyWith(curIdx: index);
+      final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+      // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+      final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+      pageStartInstanceFn(context:context);
+    }else {
+      if(isFirstInitSwitch??false){
+        final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+        // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+        final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+        pageStartInstanceFn(context:context);
+      }
+    }
+  }
+
+}
+

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

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

+ 0 - 34
packages/cpt_community/lib/modules/community/page/community_page.dart

@@ -1,34 +0,0 @@
-
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-
-import '../../../router/page/community_page_router.dart';
-import '../vm/community_view_model.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());
-    }
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.read(communityViewModelProvider.notifier);
-
-    return Scaffold(
-      appBar: AppBar(title: Text("社区")),
-      body: Center(
-        child: Text("社区主页面"),
-      ),
-    );
-  }
-}

+ 34 - 0
packages/cpt_community/lib/modules/garagesale/garagesale_page.dart

@@ -0,0 +1,34 @@
+
+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/community_page_router.dart';
+import 'garagesale_vm.dart';
+
+@RoutePage()
+class GaragesalePage extends HookConsumerWidget {
+  const GaragesalePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const GaragesalePageRoute());
+    } else {
+      appRouter.push(const GaragesalePageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _viewModel = ref.read(garagesaleVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("社区")),
+      body: Center(
+        child: Text("garage sale"),
+      ),
+    );
+  }
+}

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


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


+ 14 - 14
packages/cpt_community/lib/modules/community/vm/community_view_model.dart

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

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

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

+ 65 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_page.dart

@@ -0,0 +1,65 @@
+
+import 'package:cpt_community/components/custom_tabs.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 '../../router/page/community_page_router.dart';
+import 'newsfeed_vm.dart';
+
+@RoutePage()
+class NewsfeedPage extends HookConsumerWidget {
+  const NewsfeedPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const NewsfeedPageRoute());
+    } else {
+      appRouter.push(const NewsfeedPageRoute());
+    }
+  }
+
+  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: CustomTabs(tabsList: vm.state.tabsList, activeIndex: vm.state.activeIndex),
+    );
+  }
+
+  Widget _buildPostSection(BuildContext context, WidgetRef ref, vm){
+    return Container(
+      height: 100,
+      color: Colors.red,
+    );
+  }
+
+  Widget _buildNesFeedList(BuildContext context, WidgetRef ref, vm){
+    return Container(
+      height: 100,
+      color: Colors.blue,
+    );
+  }
+
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(newsfeedVmProvider.notifier);
+
+    return Scaffold(
+      body: Column(
+          children: [
+            _buildTabsSection(context, ref, vm),
+
+            _buildPostSection(context, ref, vm),
+
+            Expanded(
+              child: _buildNesFeedList(context, ref, vm),
+            )
+          ],
+      ),
+    );
+  }
+}

+ 0 - 0
packages/cpt_community/lib/modules/newsfeed/newsfeed_repository.dart


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

@@ -0,0 +1,23 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:shared/utils/color_utils.dart';
+
+class NewsfeedState {
+  int? activeIndex = 0;
+  List tabsList = [];
+
+  NewsfeedState({
+    this.activeIndex,
+    required this.tabsList,
+  });
+
+  NewsfeedState copyWith({
+    int? activeIndex,
+    List? tabsList,
+  }) {
+    return NewsfeedState(
+      activeIndex: activeIndex ?? this.activeIndex,
+      tabsList: tabsList ?? this.tabsList,
+    );
+  }
+}

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

@@ -0,0 +1,47 @@
+
+import 'package:flutter/material.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/color_utils.dart';
+
+import 'newsfeed_state.dart';
+
+part 'newsfeed_vm.g.dart';
+
+@riverpod
+class NewsfeedVm extends _$NewsfeedVm {
+  NewsfeedState initState() {
+    return NewsfeedState(
+      activeIndex: 0,
+      tabsList: [
+        {
+          'title': 'News',
+          'icon': null,
+          'activeTitleColor': Colors.white,
+          'activeTitleFontSize': 16,
+          'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
+        },
+        {
+          'title': 'Following',
+          'icon': null,
+          'activeTitleColor': Colors.white,
+          'activeTitleFontSize': 16,
+          'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
+        },
+        {
+          'title': 'For You',
+          'icon': null,
+          'activeTitleColor': Colors.white,
+          'activeTitleFontSize': 16,
+          'activeTitleBackgroundColor': ColorUtils.string2Color("#4161D0"),
+        }
+      ]
+    );
+  }
+  @override
+  NewsfeedState build(){
+    NewsfeedState state = initState();
+    return state;
+  }
+
+
+}

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

@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'newsfeed_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$newsfeedVmHash() => r'85ded646400393df6fe1d8fb9f9065845f36ede7';
+
+/// See also [NewsfeedVm].
+@ProviderFor(NewsfeedVm)
+final newsfeedVmProvider =
+    AutoDisposeNotifierProvider<NewsfeedVm, NewsfeedState>.internal(
+  NewsfeedVm.new,
+  name: r'newsfeedVmProvider',
+  debugGetCreateSourceHash:
+      const bool.fromEnvironment('dart.vm.product') ? null : _$newsfeedVmHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$NewsfeedVm = AutoDisposeNotifier<NewsfeedState>;
+// 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_community/lib/router/component/community_component_service.dart

@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
-import '../../modules/community/page/community_page.dart';
+import '../../modules/community/community_page.dart';
 
 part 'community_component_service.g.dart';
 

+ 20 - 3
packages/cpt_community/lib/router/page/community_page_router.dart

@@ -3,8 +3,9 @@ import 'package:flutter/material.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 
-import '../../modules/community/page/community_page.dart';
-
+import '../../modules/community/community_page.dart';
+import '../../modules/newsfeed/newsfeed_page.dart';
+import '../../modules/garagesale/garagesale_page.dart';
 
 part 'community_page_router.gr.dart';
 
@@ -16,6 +17,22 @@ class CommunityPageRouter extends _$CommunityPageRouter {
   @override
   List<AutoRoute> get routes => [
 
-    CustomRoute(page: CommunityPageRoute.page, path: RouterPath.community, transitionsBuilder: applySlideTransition),
+    CustomRoute(
+        page: CommunityPageRoute.page,
+        path: RouterPath.community,
+        transitionsBuilder: applySlideTransition,
+        children: [
+          CustomRoute(
+              page: NewsfeedPageRoute.page,
+              path: RouterPath.newsFeed,
+              transitionsBuilder: applySlideTransition,
+          ),
+          CustomRoute(
+            page: GaragesalePageRoute.page,
+            path: RouterPath.garageSale,
+            transitionsBuilder: applySlideTransition,
+          ),
+        ]
+    ),
   ];
 }

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

@@ -20,7 +20,19 @@ abstract class _$CommunityPageRouter extends RootStackRouter {
         routeData: routeData,
         child: const CommunityPage(),
       );
-    }
+    },
+    GaragesalePageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const GaragesalePage(),
+      );
+    },
+    NewsfeedPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const NewsfeedPage(),
+      );
+    },
   };
 }
 
@@ -37,3 +49,31 @@ class CommunityPageRoute extends PageRouteInfo<void> {
 
   static const PageInfo<void> page = PageInfo<void>(name);
 }
+
+/// generated route for
+/// [GaragesalePage]
+class GaragesalePageRoute extends PageRouteInfo<void> {
+  const GaragesalePageRoute({List<PageRouteInfo>? children})
+      : super(
+          GaragesalePageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'GaragesalePageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [NewsfeedPage]
+class NewsfeedPageRoute extends PageRouteInfo<void> {
+  const NewsfeedPageRoute({List<PageRouteInfo>? children})
+      : super(
+          NewsfeedPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'NewsfeedPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}

+ 6 - 6
packages/cpt_property/lib/modules/ioan/property_ioan_page.dart

@@ -168,7 +168,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                           textColor: ColorUtils.string2Color('#000000'),
                           fontSize: 14,
                           textAlign: TextAlign.center,
-                          marginLeft: 47.5,
+                          marginLeft: 50.5,
                         ),
                       ],
                     ),
@@ -186,7 +186,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                               fontSize: 16,
                               textAlign: TextAlign.center,
                               fontWeight: FontWeight.w500,
-                              marginLeft: 20,
+                              marginLeft: 15,
                             ),
                             MyTextView(
                               "2.50%",
@@ -194,7 +194,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                               fontSize: 16,
                               textAlign: TextAlign.center,
                               fontWeight: FontWeight.w500,
-                              marginLeft: 47.5,
+                              marginLeft: 50.5,
                             ),
                           ],
                         ),
@@ -207,7 +207,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                               fontSize: 16,
                               textAlign: TextAlign.center,
                               fontWeight: FontWeight.w500,
-                              marginLeft: 20,
+                              marginLeft: 15,
                             ),
                             MyTextView(
                               "2.50%",
@@ -215,7 +215,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                               fontSize: 16,
                               textAlign: TextAlign.center,
                               fontWeight: FontWeight.w500,
-                              marginLeft: 47.5,
+                              marginLeft: 50.5,
                             ),
                           ],
                         ).marginOnly(top: 15),
@@ -228,7 +228,7 @@ class PropertyIoanPage extends HookConsumerWidget {
                               fontSize: 16,
                               textAlign: TextAlign.center,
                               fontWeight: FontWeight.w500,
-                              marginLeft: 20,
+                              marginLeft: 15,
                             ),
                             MyTextView(
                               "2.50%",

+ 71 - 0
packages/cpt_property/lib/modules/ioan/property_ioan_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 'property_ioan_state.dart';
+
+part 'property_ioan_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+PropertyIoanRepository propertyIoanRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return PropertyIoanRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class PropertyIoanRepository {
+  DioEngine dioEngine;
+
+  PropertyIoanRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyIoanList(
+      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 = PropertyIoanState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<PropertyIoanState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 13 - 11
packages/cpt_community/lib/modules/community/vm/community_view_model.g.dart

@@ -1,27 +1,29 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
 
-part of 'community_view_model.dart';
+part of 'property_ioan_repository.dart';
 
 // **************************************************************************
 // RiverpodGenerator
 // **************************************************************************
 
-String _$communityViewModelHash() =>
-    r'3902087cb4011dabd629a95c51d23b3081dd5f80';
+String _$propertyIoanRepositoryHash() =>
+    r'a6733dbd000218cbd4eb05a400ca497ffbebb7aa';
 
-/// See also [CommunityViewModel].
-@ProviderFor(CommunityViewModel)
-final communityViewModelProvider =
-    AutoDisposeNotifierProvider<CommunityViewModel, void>.internal(
-  CommunityViewModel.new,
-  name: r'communityViewModelProvider',
+/// See also [propertyIoanRepository].
+@ProviderFor(propertyIoanRepository)
+final propertyIoanRepositoryProvider =
+    Provider<PropertyIoanRepository>.internal(
+  propertyIoanRepository,
+  name: r'propertyIoanRepositoryProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
       ? null
-      : _$communityViewModelHash,
+      : _$propertyIoanRepositoryHash,
   dependencies: null,
   allTransitiveDependencies: null,
 );
 
-typedef _$CommunityViewModel = AutoDisposeNotifier<void>;
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef PropertyIoanRepositoryRef = ProviderRef<PropertyIoanRepository>;
 // 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

+ 17 - 0
packages/cpt_property/lib/modules/ioan/property_ioan_state.dart

@@ -36,4 +36,21 @@ class PropertyIoanState {
         "lowestFixedRate": lowestFixedRate,
         "othersOfferingInfoList": List<dynamic>.from(othersOfferingInfoList.map((x) => x)),
     };
+
+    PropertyIoanState copyWith({
+    List<dynamic>? offerTextInfoList,
+    String? lowestFloatingRate,
+    String? othersOfferingPic,
+    String? lowestFixedRate,
+    List<dynamic>? othersOfferingInfoList,
+  }) {
+    return PropertyIoanState(
+      offerTextInfoList: offerTextInfoList ?? this.offerTextInfoList,
+      lowestFloatingRate: lowestFloatingRate ?? this.lowestFloatingRate,
+      othersOfferingPic: othersOfferingPic ?? this.othersOfferingPic,
+      lowestFixedRate: lowestFixedRate ?? this.lowestFixedRate,
+      othersOfferingInfoList:
+          othersOfferingInfoList ?? this.othersOfferingInfoList,
+    );
+  }
 }

+ 1 - 1
packages/cpt_property/lib/modules/ioan/property_ioan_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_ioan_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertyIoanVmHash() => r'0a144f8492752958fa349425ff3a3e2fe631b733';
+String _$propertyIoanVmHash() => r'30a52b0e2e7a252f4c8bc8c8401bdafbd95a2604';
 
 /// See also [PropertyIoanVm].
 @ProviderFor(PropertyIoanVm)

+ 22 - 22
packages/cpt_property/lib/modules/property/page/property_page.dart

@@ -1,3 +1,4 @@
+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';
@@ -7,6 +8,7 @@ import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_text_view.dart';
+import 'package:widgets/my_appbar.dart';
 
 import '../../../router/page/property_page_router.dart';
 import '../vm/property_vm.dart';
@@ -74,28 +76,26 @@ class PropertyPage extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final _vm = ref.read(propertyVmProvider.notifier);
-    return DefaultTabController(
-      length: 4,
-      child: Scaffold(
-          appBar: AppBar(
-            title: const Text("Property"),
-            bottomOpacity: 0.0, // 取消下横线
-            titleTextStyle: const TextStyle(color: Colors.black),
-          ),
-          body: Row(
-            children: [
-              Expanded(
-                child: Column(
-                  children: [
-                    _buildTopSection(context, ref, _vm),
-                    const Expanded(
-                      child: AutoRouter(),
-                    )
-                  ],
-                ),
-              )
-            ],
-          )),
+    return Scaffold(
+        appBar: MyAppBar.appBar(
+          context,
+          "Property",
+          backgroundColor: context.appColors.whiteBG,
+        ),
+        body: Row(
+          children: [
+            Expanded(
+              child: Column(
+                children: [
+                  _buildTopSection(context, ref, _vm),
+                  const Expanded(
+                    child: AutoRouter(),
+                  )
+                ],
+              ),
+            )
+          ],
+        )
     );
   }
 }

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

@@ -73,6 +73,9 @@ class Assets {
   static const String mainTabMeUnselected = 'assets/main/tab_me_unselected.webp';
   static const String mainTabVisitorSelected = 'assets/main/tab_visitor_selected.webp';
   static const String mainTabVisitorUnselected = 'assets/main/tab_visitor_unselected.webp';
+  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 propertyAdvicePic = 'assets/property/advice_pic.webp';
   static const String propertyApproval = 'assets/property/approval.webp';
   static const String propertyCollection = 'assets/property/collection.webp';

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

@@ -33,6 +33,8 @@ class RouterPath {
 
   //社区
   static const community = '/community';
+  static const newsFeed = 'community/news_feed';
+  static const garageSale = 'community/garage_sale';
 
   //设施
   static const facility = '/facility';