Browse Source

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

“shanwenxin” 3 months ago
parent
commit
c823a96f32
100 changed files with 2840 additions and 1427 deletions
  1. 1 1
      app/android/app/src/main/res/drawable-v21/launch_background.xml
  2. BIN
      app/android/app/src/main/res/drawable-xhdpi/yy_business_top_logo.webp
  3. BIN
      app/android/app/src/main/res/drawable-xhdpi/yyhome_splash.png
  4. BIN
      app/android/app/src/main/res/drawable-xxhdpi/yy_business_top_logo.webp
  5. BIN
      app/android/app/src/main/res/drawable-xxhdpi/yyhome_splash.png
  6. 1 1
      app/android/app/src/main/res/drawable/launch_background.xml
  7. 1 6
      app/android/app/src/main/res/drawable/shape_page_bg.xml
  8. 12 12
      app/ios/Runner.xcodeproj/project.pbxproj
  9. 6 6
      app/ios/Runner/Info.plist
  10. 0 2
      app/lib/main.dart
  11. 9 25
      app/lib/modules/splash/page/splash_page.dart
  12. 1 1
      melos.yaml
  13. 1 1
      packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart
  14. 29 33
      packages/cpt_auth/lib/modules/sign_up/sign_up_page.dart
  15. 8 11
      packages/cpt_community/lib/components/garage_card.dart
  16. 2 0
      packages/cpt_community/lib/modules/community/community_page.dart
  17. 0 8
      packages/cpt_community/lib/modules/community/community_pageview_idx_data.dart
  18. 3 0
      packages/cpt_community/lib/modules/community/following/following_vm.dart
  19. 3 0
      packages/cpt_community/lib/modules/community/foryou/foryou_vm.dart
  20. 3 1
      packages/cpt_community/lib/modules/community/news/news_vm.dart
  21. 2 2
      packages/cpt_community/lib/modules/community/newsfeed_detail/newsfeed_detail_page.dart
  22. 4 0
      packages/cpt_community/lib/modules/community/newsfeed_detail/newsfeed_detail_vm.dart
  23. 8 2
      packages/cpt_community/lib/modules/community/newsfeed_post/newsfeed_post_vm.dart
  24. 1 1
      packages/cpt_community/lib/modules/garage/for_sale/for_sale_page.dart
  25. 36 15
      packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_page.dart
  26. 1 1
      packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_state.dart
  27. 1 1
      packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_vm.dart
  28. 7 3
      packages/cpt_community/lib/modules/garage/garagesale_post/garagesale_post_vm.dart
  29. 4 0
      packages/cpt_community/lib/modules/my_following/components/item_following_vm.dart
  30. 19 19
      packages/cpt_facility/lib/modules/booking/facility_booking_page.dart
  31. 1 1
      packages/cpt_facility/lib/modules/booking/facility_booking_view_model.dart
  32. 1 1
      packages/cpt_facility/lib/modules/booking/facility_booking_view_model.g.dart
  33. 1 1
      packages/cpt_facility/lib/modules/detail/facility_detail_view_model.g.dart
  34. 1 2
      packages/cpt_facility/lib/modules/facility/book/facility_book_screen.dart
  35. 1 1
      packages/cpt_facility/lib/modules/facility/book/facility_book_view_model.g.dart
  36. 1 0
      packages/cpt_facility/lib/router/page/facility_page_router.dart
  37. 6 12
      packages/cpt_facility/lib/router/page/facility_page_router.gr.dart
  38. 6 6
      packages/cpt_main/lib/modules/feedback/feedback_page.dart
  39. 187 89
      packages/cpt_main/lib/modules/home/home_page.dart
  40. 75 96
      packages/cpt_main/lib/modules/home/home_state.dart
  41. 43 3
      packages/cpt_main/lib/modules/home/home_view_model.dart
  42. 4 2
      packages/cpt_main/lib/modules/home/item_home_last_news.dart
  43. 16 15
      packages/cpt_main/lib/modules/home/item_home_last_trans.dart
  44. 7 9
      packages/cpt_main/lib/modules/home/item_home_manage_guide.dart
  45. 6 3
      packages/cpt_main/lib/modules/home/item_home_property_news.dart
  46. 18 6
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_screen.dart
  47. 3 2
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_state.dart
  48. 64 70
      packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.dart
  49. 15 1
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_screen.dart
  50. 3 2
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_state.dart
  51. 64 71
      packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.dart
  52. 84 0
      packages/cpt_main/lib/modules/home/latest_news/item_latest_news.dart
  53. 15 2
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_screen.dart
  54. 3 2
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_state.dart
  55. 62 69
      packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.dart
  56. 19 6
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_screen.dart
  57. 3 2
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_state.dart
  58. 64 70
      packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.dart
  59. 6 7
      packages/cpt_main/lib/modules/home/management_guides/item_management_guide.dart
  60. 4 3
      packages/cpt_main/lib/modules/home/management_guides/management_guides_page.dart
  61. 3 3
      packages/cpt_main/lib/modules/home/management_guides/management_guides_state.dart
  62. 59 81
      packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.dart
  63. 0 4
      packages/cpt_main/lib/modules/home/management_guides/test_guide_bean.dart
  64. 5 2
      packages/cpt_main/lib/modules/home/property_news/home_property_news_page.dart
  65. 3 2
      packages/cpt_main/lib/modules/home/property_news/home_property_news_state.dart
  66. 44 67
      packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.dart
  67. 5 4
      packages/cpt_main/lib/modules/home/property_news/item_list_news.dart
  68. 21 1
      packages/cpt_main/lib/modules/main/main_view_model.dart
  69. 0 1
      packages/cpt_main/lib/modules/visitor/item_visitor.dart
  70. 6 6
      packages/cpt_main/lib/modules/visitor/visitor_page.dart
  71. 4 1
      packages/cpt_profile/lib/modules/setting/setting_page.dart
  72. 7 0
      packages/cpt_profile/lib/modules/setting/setting_view_model.dart
  73. 22 22
      packages/cpt_property/lib/modules/ioan/property_ioan_page.dart
  74. 6 6
      packages/cpt_property/lib/modules/news/page/property_news_page.dart
  75. 21 2
      packages/cpt_property/lib/modules/news/vm/property_news_vm.dart
  76. 1 1
      packages/cpt_property/lib/modules/news/vm/property_news_vm.g.dart
  77. 115 13
      packages/cpt_property/lib/modules/news_detail/property_news_detail_page.dart
  78. 16 4
      packages/cpt_property/lib/modules/news_detail/property_news_detail_state.dart
  79. 268 9
      packages/cpt_property/lib/modules/news_detail/property_news_detail_vm.dart
  80. 1 1
      packages/cpt_property/lib/modules/news_detail/property_news_detail_vm.g.dart
  81. 32 0
      packages/cpt_property/lib/modules/property/page/property_page.dart
  82. 51 0
      packages/cpt_property/lib/modules/property/page/property_page_state.dart
  83. 22 62
      packages/cpt_property/lib/modules/property/vm/property_vm.dart
  84. 1 1
      packages/cpt_property/lib/modules/property/vm/property_vm.g.dart
  85. 1 1
      packages/cpt_property/lib/modules/rent/vm/property_rent_vm.g.dart
  86. 1 1
      packages/cpt_property/lib/modules/sale/vm/property_sale_vm.g.dart
  87. 42 0
      packages/cpt_property/lib/respository/property_resposity.dart
  88. 6 0
      packages/cpt_property/lib/router/component/property_component_service.dart
  89. 9 9
      packages/cpt_property/lib/router/page/property_page_router.gr.dart
  90. 19 0
      packages/cpt_services/lib/constants_services.dart
  91. 0 123
      packages/cpt_services/lib/modules/services/dialog/account_deactivation_dialog.dart
  92. 148 0
      packages/cpt_services/lib/modules/services/homeService/home_service_page.dart
  93. 44 0
      packages/cpt_services/lib/modules/services/homeService/home_service_state.dart
  94. 337 0
      packages/cpt_services/lib/modules/services/homeService/home_service_vm.dart
  95. 10 10
      packages/cpt_services/lib/modules/services_detail/services_detail_vm.g.dart
  96. 231 0
      packages/cpt_services/lib/modules/services/homeService/service_card_item.dart
  97. 320 214
      packages/cpt_services/lib/modules/services/services_page.dart
  98. 13 0
      packages/cpt_services/lib/modules/services/services_pageview_idx_data.dart
  99. 0 70
      packages/cpt_services/lib/modules/services/services_repository.dart
  100. 0 0
      packages/cpt_services/lib/modules/services/services_state.dart

+ 1 - 1
app/android/app/src/main/res/drawable-v21/launch_background.xml

@@ -5,7 +5,7 @@
     <item >
         <bitmap
             android:gravity="center"
-            android:src="@drawable/yy_business_top_logo"/>
+            android:src="@drawable/yyhome_splash"/>
     </item>
 
 </layer-list>

BIN
app/android/app/src/main/res/drawable-xhdpi/yy_business_top_logo.webp


BIN
app/android/app/src/main/res/drawable-xhdpi/yyhome_splash.png


BIN
app/android/app/src/main/res/drawable-xxhdpi/yy_business_top_logo.webp


BIN
app/android/app/src/main/res/drawable-xxhdpi/yyhome_splash.png


+ 1 - 1
app/android/app/src/main/res/drawable/launch_background.xml

@@ -5,7 +5,7 @@
     <item >
         <bitmap
             android:gravity="center"
-            android:src="@drawable/yy_business_top_logo"/>
+            android:src="@drawable/yyhome_splash"/>
     </item>
 
 </layer-list>

+ 1 - 6
app/android/app/src/main/res/drawable/shape_page_bg.xml

@@ -2,11 +2,6 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle">
 
-    <gradient
-        android:startColor="#091D44"
-        android:centerColor="#245A8A"
-        android:endColor="#7F7CEC"
-        android:type="linear"
-        android:angle="270" />
+    <solid android:color="#FFFFFF" /> <!-- 设置为纯白色 -->
 
 </shape>

+ 12 - 12
app/ios/Runner.xcodeproj/project.pbxproj

@@ -396,19 +396,19 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
-				CURRENT_PROJECT_VERSION = 1.0.5;
+				CURRENT_PROJECT_VERSION = 1.0;
 				DEVELOPMENT_TEAM = CW4J9W8LB6;
 				ENABLE_BITCODE = NO;
 				FLUTTER_BUILD_MODE = profile;
 				INFOPLIST_FILE = Runner/Info.plist;
-				INFOPLIST_KEY_CFBundleDisplayName = "YY Employers";
+				INFOPLIST_KEY_CFBundleDisplayName = "YY Home";
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.guadou.YYEmployer;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.hongyegroup.YYHome;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
 				SUPPORTS_MACCATALYST = NO;
@@ -537,19 +537,19 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
-				CURRENT_PROJECT_VERSION = 1.0.5;
+				CURRENT_PROJECT_VERSION = 1.0;
 				DEVELOPMENT_TEAM = CW4J9W8LB6;
 				ENABLE_BITCODE = NO;
 				FLUTTER_BUILD_MODE = debug;
 				INFOPLIST_FILE = Runner/Info.plist;
-				INFOPLIST_KEY_CFBundleDisplayName = "YY Employers";
+				INFOPLIST_KEY_CFBundleDisplayName = "YY Home";
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.guadou.YYEmployer;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.hongyegroup.YYHome;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
 				SUPPORTS_MACCATALYST = NO;
@@ -570,19 +570,19 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
-				CURRENT_PROJECT_VERSION = 1.0.5;
+				CURRENT_PROJECT_VERSION = 1.0;
 				DEVELOPMENT_TEAM = CW4J9W8LB6;
 				ENABLE_BITCODE = NO;
 				FLUTTER_BUILD_MODE = release;
 				INFOPLIST_FILE = Runner/Info.plist;
-				INFOPLIST_KEY_CFBundleDisplayName = "YY Employers";
+				INFOPLIST_KEY_CFBundleDisplayName = "YY Home";
 				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.guadou.YYEmployer;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.hongyegroup.YYHome;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
 				SUPPORTS_MACCATALYST = NO;

+ 6 - 6
app/ios/Runner/Info.plist

@@ -7,7 +7,7 @@
 	<key>CFBundleDevelopmentRegion</key>
 	<string>$(DEVELOPMENT_LANGUAGE)</string>
 	<key>CFBundleDisplayName</key>
-	<string>YY Employers</string>
+	<string>YY Home</string>
 	<key>CFBundleExecutable</key>
 	<string>$(EXECUTABLE_NAME)</string>
 	<key>CFBundleIdentifier</key>
@@ -68,15 +68,15 @@
 		<true/>
 	</dict>
 	<key>NSCameraUsageDescription</key>
-	<string>“YY Employers”apply for your camera permission to use functions such as taking avatars, uploading videos, uploading and saving pictures, and real-name authentication.</string>
+	<string>“YY Home”apply for your camera permission to use functions such as taking avatars, uploading videos, uploading and saving pictures, and real-name authentication.</string>
 	<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
-	<string>YY Employers needs your location to recommend nearby jobs</string>
+	<string>YY Home needs your location to recommend nearby jobs</string>
 	<key>NSLocationWhenInUseUsageDescription</key>
-	<string>YY Employers needs your location to recommend nearby jobs.</string>
+	<string>YY Home needs your location to recommend nearby jobs.</string>
 	<key>NSPhotoLibraryAddUsageDescription</key>
-	<string>"YY Employers" wants to access your photos for image upload, image saving and other functions.</string>
+	<string>"YY Home" wants to access your photos for image upload, image saving and other functions.</string>
 	<key>NSPhotoLibraryUsageDescription</key>
-	<string>"YY Employers" wants to access your photos for image upload, image saving and other functions.</string>
+	<string>"YY Home" wants to access your photos for image upload, image saving and other functions.</string>
 	<key>NSUserTrackingUsageDescription</key>
 	<string>This identifier will be used to deliver personalized job to you.</string>
 	<key>UIApplicationSupportsIndirectInputEvents</key>

+ 0 - 2
app/lib/main.dart

@@ -118,7 +118,6 @@ class MyApp extends HookConsumerWidget {
     int? darkModel = SPUtil.getInt(AppConstant.storageDarkModel, defValue: 0);
     late SystemUiOverlayStyle systemUiOverlayStyle;
 
-    if (DeviceUtils.isAndroid) {
       //根据SP存入的暗色模式,指定全局页面的状态栏,导航栏等设置
       switch (darkModel) {
         case 1:
@@ -133,7 +132,6 @@ class MyApp extends HookConsumerWidget {
           systemUiOverlayStyle = ThemeConfig.getSystemUiOverlayStyleByTheme(context);
           break;
       }
-    }
 
     SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
 

+ 9 - 25
app/lib/modules/splash/page/splash_page.dart

@@ -1,12 +1,10 @@
+import 'package:app/main.dart';
 import 'package:app/router/page/app_page_router.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:cs_resources/generated/assets.dart';
-import 'package:router/componentRouter/app_service.dart';
-import 'package:router/path/router_path.dart';
 import 'package:shared/utils/size_config.dart';
-import 'package:widgets/dialog/custom_error_widget.dart';
-import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:auto_route/annotations.dart';
 import '../vm/splash_view_model.dart';
@@ -23,27 +21,13 @@ class SplashPage extends HookConsumerWidget {
    final viewModel = ref.watch(splashViewModelProvider.notifier)..setContext(context);
 
     return Scaffold(
-      body: Container(
-        decoration: const BoxDecoration(
-          gradient: LinearGradient(
-            colors: [
-              Color(0xFF091D44),
-              Color(0xFF245A8A),
-              Color(0xFF7F7CEC),
-            ],
-            begin: Alignment.topCenter,
-            end: Alignment.bottomCenter,
-          ),
-        ),
-        child:  Center(
-          child: const MyAssetImage(
-            Assets.assetsYyBusinessTopLogo,
-            width: 166,
-            height: 67.5,
-            fit: BoxFit.contain,
-          ).onTap((){
-            context.router.pushNamed(RouterPath.main);
-          }),
+      backgroundColor: context.appColors.backgroundWhite,
+      body: const Center(
+        child: MyAssetImage(
+          Assets.assetsYyHomeSplash,
+          width: 84.5,
+          height: 100,
+          fit: BoxFit.contain,
         ),
       ),
     );

+ 1 - 1
melos.yaml

@@ -88,7 +88,7 @@ scripts:
     description: Run `dart run build_runner build` in rewards module
 
   build_runner_services:
-    run: cd "$MELOS_ROOT_PATH/packages/cpt_services" && dart run build_runner build --delete-conflicting-outputs
+    run: cd "$MELOS_ROOT_PATH/packages/cpt_services" && flutter pub run build_runner build --delete-conflicting-outputs --verbose
     description: Run `dart run build_runner build` in services module
 
   clean_all:

+ 1 - 1
packages/cpt_auth/lib/modules/select_estate/select_estate_page.dart

@@ -63,7 +63,7 @@ class SelectEstatePage extends HookConsumerWidget with WidgetsBindingObserver {
         padding: const EdgeInsets.symmetric(horizontal: 38),
         width: double.infinity,
         child: VisibilityDetector(
-          key: Key('select-estate-page'),
+          key: const Key('select-estate-page'),
           onVisibilityChanged: (VisibilityInfo info) {
             // 检测页面是否可见
             isVisible = info.visibleFraction > 0;

+ 29 - 33
packages/cpt_auth/lib/modules/sign_up/sign_up_page.dart

@@ -1,4 +1,3 @@
-
 import 'package:cpt_auth/modules/sign_up/sign_up_state.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
@@ -124,7 +123,6 @@ class SignUpPage extends HookConsumerWidget {
                     context,
                     state,
                     "phone",
-                    marginTop: 15,
                     textInputType: TextInputType.number,
                     textInputAction: TextInputAction.next,
                     errorText: state.phoneErrorText,
@@ -134,7 +132,7 @@ class SignUpPage extends HookConsumerWidget {
                     },
                   ).expanded(),
                 ],
-              ),
+              ).marginOnly(top: 15),
 
               // 表单 - 重置密码
               _buildInputLayout(
@@ -151,15 +149,15 @@ class SignUpPage extends HookConsumerWidget {
                   splashColor: Colors.transparent,
                   icon: state.pwdVisibility
                       ? const MyAssetImage(
-                    Assets.authPasswordHide,
-                    width: 22.5,
-                    height: 16.5,
-                  )
+                          Assets.authPasswordHide,
+                          width: 22.5,
+                          height: 16.5,
+                        )
                       : const MyAssetImage(
-                    Assets.authPasswordShow,
-                    width: 22.5,
-                    height: 16.5,
-                  ),
+                          Assets.authPasswordShow,
+                          width: 22.5,
+                          height: 16.5,
+                        ),
                   onPressed: () {
                     viewModel.switchPwdVisibility();
                   },
@@ -184,15 +182,15 @@ class SignUpPage extends HookConsumerWidget {
                   splashColor: Colors.transparent,
                   icon: state.confirmPwdVisibility
                       ? const MyAssetImage(
-                    Assets.authPasswordHide,
-                    width: 22.5,
-                    height: 16.5,
-                  )
+                          Assets.authPasswordHide,
+                          width: 22.5,
+                          height: 16.5,
+                        )
                       : const MyAssetImage(
-                    Assets.authPasswordShow,
-                    width: 22.5,
-                    height: 16.5,
-                  ),
+                          Assets.authPasswordShow,
+                          width: 22.5,
+                          height: 16.5,
+                        ),
                   onPressed: () {
                     viewModel.switchConfirmPwdVisibility();
                   },
@@ -244,7 +242,6 @@ class SignUpPage extends HookConsumerWidget {
                   ),
                 ],
               ).marginOnly(bottom: 35),
-
             ],
           ),
         ),
@@ -254,18 +251,18 @@ class SignUpPage extends HookConsumerWidget {
 
   /// 输入框
   Widget _buildInputLayout(
-      BuildContext context,
-      SignUpState 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,
-      }) {
+    BuildContext context,
+    SignUpState 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,
@@ -300,5 +297,4 @@ class SignUpPage extends HookConsumerWidget {
       ),
     );
   }
-
 }

+ 8 - 11
packages/cpt_community/lib/components/garage_card.dart

@@ -76,20 +76,17 @@ class GarageCard extends StatelessWidget {
                 child: MyLoadImage(
                   card_img,
                   width: 166.5,
-                  height: 102.5,
+                  height: 102.5.ap,
                   isCircle: false,
                   fit: BoxFit.cover,
-                ).onTap(() {
-                  // 点击头像
-                  // onTap?.call();
-                }),
+                ),
               ),
             ),
           ],
         ),
         // 标题
         Padding(
-          padding: const EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12),
+          padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
           child: Row(
             mainAxisAlignment: MainAxisAlignment.center,
             children: [
@@ -109,7 +106,7 @@ class GarageCard extends StatelessWidget {
         ),
         // 价格 及 收藏
         Padding(
-          padding: const EdgeInsets.only(left: 10, right: 10,top: 10, bottom: 10),
+          padding: const EdgeInsets.only(left: 10, right: 10,top: 0, bottom: 0),
           child: Row(
             mainAxisAlignment: MainAxisAlignment.spaceAround,
             crossAxisAlignment: CrossAxisAlignment.center,
@@ -134,10 +131,10 @@ class GarageCard extends StatelessWidget {
             ],
           ),
         ),
-          // 发布人信息
-          Expanded(
+        // 发布人信息
+        Expanded(
           child: Padding(
-            padding: EdgeInsets.only(left: (useType == GarageCardUseType.forSale || useType == GarageCardUseType.forRent)?10:0, right: 10),
+            padding: EdgeInsets.only(left: (useType == GarageCardUseType.forSale || useType == GarageCardUseType.forRent)?10:0, right: 10, bottom: 17.5),
             child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceAround,
               crossAxisAlignment: CrossAxisAlignment.center,
@@ -229,7 +226,7 @@ class CollectionWidget extends HookConsumerWidget {
           ),
           MyLoadImage(
             isCollectionState.value? Assets.communityLikeActive: Assets.communityLike,
-            width: 15,
+            width: 14.1,
             height: 14,
           )
         ]

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

@@ -94,6 +94,8 @@ class CommunityPage extends HookConsumerWidget with WidgetsBindingObserver {
           WidgetsBinding.instance.addObserver(this);
         }, []);
 
+
+
         useEffect((){
           Log.d("CommunityPage initState");
           // 延迟监听

+ 0 - 8
packages/cpt_community/lib/modules/community/community_pageview_idx_data.dart

@@ -1,11 +1,3 @@
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-
-import '../garage/for_rent/for_rent_vm.dart';
-import '../garage/for_sale/for_sale_vm.dart';
-import 'following/following_vm.dart';
-import 'foryou/foryou_vm.dart';
-import 'news/news_state.dart';
-import 'news/news_vm.dart';
 
 class CommunityPageViewIdxData {
   static const int news = 0;

+ 3 - 0
packages/cpt_community/lib/modules/community/following/following_vm.dart

@@ -1,6 +1,7 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:domain/entity/newsfeed_following_entity.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.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';
@@ -271,6 +272,8 @@ class FollowingVm extends _$FollowingVm {
           });
           state = state.copyWith(list: listCopyDta);
         }
+        // 同步用户信息
+        UserConfigService.getInstance().refreshUserInfo();
         return true;
       }else {
         return false;

+ 3 - 0
packages/cpt_community/lib/modules/community/foryou/foryou_vm.dart

@@ -1,6 +1,7 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:domain/entity/newsfeed_foryou_entity.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.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';
@@ -274,6 +275,8 @@ class ForyouVm extends _$ForyouVm {
           });
           state = state.copyWith(list: listCopyDta);
         }
+        // 同步用户信息
+        UserConfigService.getInstance().refreshUserInfo();
         return true;
       }else {
         return false;

+ 3 - 1
packages/cpt_community/lib/modules/community/news/news_vm.dart

@@ -2,6 +2,7 @@ import 'package:cpt_community/respository/common_newsfeed.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:domain/entity/newsfeed_news_entity.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.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';
@@ -103,7 +104,6 @@ class NewsVm extends _$NewsVm {
       _page = 1;
       _needShowPlaceholder = true;
       getListData();
-      Log.d("99999999");
       // refreshController.callRefresh();
   }
 
@@ -281,6 +281,8 @@ class NewsVm extends _$NewsVm {
           });
           state = state.copyWith(list: listCopyDta);
         }
+        // 同步用户信息
+        UserConfigService.getInstance().refreshUserInfo();
         return true;
       }else {
         return false;

+ 2 - 2
packages/cpt_community/lib/modules/community/newsfeed_detail/newsfeed_detail_page.dart

@@ -136,7 +136,7 @@ class NewsfeedDetailPage extends HookConsumerWidget {
     return Stack(
       children: [
         Container(
-          margin: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 14),
+          margin: const EdgeInsets.only(left: 15, right: 15,top: 14,bottom: 0),
           padding: const EdgeInsets.only(left: 15, right: 15,top: 17,bottom: 17),
           decoration: BoxDecoration(
               color: context.appColors.textWhite,
@@ -225,7 +225,7 @@ class NewsfeedDetailPage extends HookConsumerWidget {
     return HookBuilder(
       builder: (context) {
         return Container(
-          margin: const EdgeInsets.only(left: 15, right: 15,top: 18,bottom: 18),
+          margin: const EdgeInsets.only(left: 15, right: 15,top: 15,bottom: 18),
           padding: const EdgeInsets.only(bottom: 30),
           decoration: BoxDecoration(
               color: context.appColors.textWhite,

+ 4 - 0
packages/cpt_community/lib/modules/community/newsfeed_detail/newsfeed_detail_vm.dart

@@ -8,6 +8,7 @@ import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:domain/entity/newsfeed_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -255,6 +256,9 @@ class NewsfeedDetailVm extends _$NewsfeedDetailVm {
         card_account.followed = !(card_account!.followed?? false);
         state = state.copyWith(detailInfo: detailInfoDta);
       }
+
+      // 同步用户信息
+      UserConfigService.getInstance().refreshUserInfo();
     }
     return result;
   }

+ 8 - 2
packages/cpt_community/lib/modules/community/newsfeed_post/newsfeed_post_vm.dart

@@ -2,11 +2,14 @@
 import 'package:cpt_community/respository/common_newsfeed.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/event_bus.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:shared/utils/util.dart';
@@ -133,9 +136,9 @@ class NewsfeedPostVm extends _$NewsfeedPostVm {
       return false;
     }
 
-    bool resResult = await handlerSubmitPostNewsfeed(mindValue, state.imgList,  sCallback: sCallback, fCallback: fCallback);
+    final resResult = await handlerSubmitPostNewsfeed(mindValue, state.imgList,  sCallback: sCallback, fCallback: fCallback);
 
-    if(resResult){
+    if(resResult!=null && resResult){
       final communitVm = ref.read(communityVmProvider.notifier);
       communitVm.getCurrentPageViewVm(null).initPageData();
       // Navigator.pop(context);
@@ -143,6 +146,7 @@ class NewsfeedPostVm extends _$NewsfeedPostVm {
     }
   }
 
+  // 发布
   Future<bool> handlerSubmitPostNewsfeed(String mindValue,List<String> imgList,{VoidCallback? sCallback, VoidCallback? fCallback}) async{
     try {
       final result = await repositoryInstance.fetchNewsfeedPublish({
@@ -151,6 +155,8 @@ class NewsfeedPostVm extends _$NewsfeedPostVm {
       });
       if (result.isSuccess) {
         sCallback?.call();
+        // 更新用户信息
+        UserConfigService.getInstance().refreshUserInfo();
         return true;
       }else {
         fCallback?.call();

+ 1 - 1
packages/cpt_community/lib/modules/garage/for_sale/for_sale_page.dart

@@ -93,7 +93,7 @@ class ForsalePage extends HookConsumerWidget {
                   crossAxisSpacing: 15,
                   // childAspectRatio: 166.5/214, // 宽高比
                   // childAspectRatio:  166.5/214 * ScreenUtil.getAdapterSizeCtx(context, 166.5/214), // 宽高比
-                  childAspectRatio: 166.5/214 * ((166.5/214).ap), // 宽高比
+                  childAspectRatio:  166.5/214 * ((166.5/214).ap), // 宽高比
                 ),
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {

+ 36 - 15
packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_page.dart

@@ -8,9 +8,14 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_basic/provider/app_config/app_config.dart';
+import 'package:plugin_basic/provider/app_config/app_config_service.dart';
+import 'package:plugin_platform/engine/image/image_preview.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/ext_dart.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/size_config.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/my_appbar.dart';
@@ -42,15 +47,14 @@ class GaragesaleDetailPage extends HookConsumerWidget {
     final String pageTitle = (type == 'forSale') ? 'For Sale' :'For Rent';
     GlobalKey _likeButtonKey = GlobalKey<MyLikeButtonState>();
 
-    GarageSaleRentDetailEntity detailInfo = state.datas?? GarageSaleRentDetailEntity();
-    String title =  detailInfo.title?? '';
-    int price =  detailInfo.price?? 0;
+    GarageSaleRentDetailEntity? detailInfo = state.datas?? null;
+    String title =  detailInfo?.title?? '';
+    int price =  detailInfo?.price?? 0;
 
-    String contactType =  detailInfo.contact??'';
+    String contactType =  detailInfo?.contact??'';
 
     String description = '';
 
-
     useEffect((){
       vm.setInitPageData(id: id!, type: type);
       // 组件挂载时执行 - 执行接口请求
@@ -98,7 +102,7 @@ class GaragesaleDetailPage extends HookConsumerWidget {
                       SliverList(
                         delegate: SliverChildBuilderDelegate(
                                 (context, index){
-                              return _buildContentBox(context, ref, detailInfo);
+                              return detailInfo !=null? _buildContentBox(context, ref, detailInfo): Container();
                             },
                             childCount: 1
                         ),
@@ -124,13 +128,13 @@ class GaragesaleDetailPage extends HookConsumerWidget {
           // 底部联系信息
           Visibility(
             visible: state.loadingState == LoadState.State_Success,
-            child: _buildBottomConcatInfo(context, ref, _likeButtonKey,
+            child: detailInfo !=null ? _buildBottomConcatInfo(context, ref, _likeButtonKey,
               title:title,
               price:price,
               contactType:contactType,
               description:description,
               detailInfo:detailInfo,
-            ),
+            ): Container(),
           )
         ],
       ),
@@ -165,17 +169,29 @@ class GaragesaleDetailPage extends HookConsumerWidget {
       children: [
         // 图片
         SizedBox(
-          width: double.infinity,
+          width: SizeConfig().screenWidth,
           height: 173.5,
           child: CarouselSlider(
             // items: [MyLoadImage(goods_img)] ,
-            items: resources.map((resource) => MyLoadImage(resource)).toList(),
+            items: resources.map((resource) => MyLoadImage(
+              resource,
+              fit: BoxFit.cover, // 确保图片覆盖整个区域
+              width: SizeConfig().screenWidth, // 确保图片宽度与屏幕宽度一致
+              height: 173.5, // 确保图片高度与 CarouselSlider 高度一致
+            ).onTap((){
+              ImagePreviewEngine.multipleImagePreview(
+                  context,
+                  resources,
+                  heroes: List.generate(resources.length, (index) => resources[index]),
+                  onLongPressAction: (url) {}
+              );
+            })
+            ).toList(),
             carouselController: buttonCarouselController,
             options: CarouselOptions(
-              autoPlay: true,
+              autoPlay: false,
               enlargeCenterPage: true,
-              viewportFraction: 0.9,
-              aspectRatio: 2.0,
+              viewportFraction: 1,
               initialPage: 0,
             ),
           ),
@@ -221,15 +237,20 @@ class GaragesaleDetailPage extends HookConsumerWidget {
 
     GarageSaleRentDetailAccount  account = detailInfo.account?? GarageSaleRentDetailAccount();
 
+    Log.d("0000000 ${detailInfo.likesCount}");
     String publisher =  account.name??'-';
     String publisherAvatar = account.avatar??'-';
 
     String contactType =  detailInfo.contact??'';
     String publisherTime =  detailInfo.createdAt??'-';
-    int likes_count =  detailInfo!.likesCount??0;
+    int? likes_count =  detailInfo.likesCount??0;
+    Log.d("666666 ${likes_count}");
 
-    final _likes_count = useState(likes_count);
+
+    final _likes_count = useState<int>(likes_count!);
     final _isLiked = useState<bool>(false);
+    Log.d("4344 ${_likes_count.value}");
+
 
     return Container(
       height: 50,

+ 1 - 1
packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_state.dart

@@ -9,7 +9,7 @@ class GarageDetailState {
   final int? id;
   final String? type;  // forsale  forrent
 
-  GarageSaleRentDetailEntity datas;
+  GarageSaleRentDetailEntity? datas;
 
   GarageDetailState({
     this.loadingState = LoadState.State_Loading,

+ 1 - 1
packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_vm.dart

@@ -39,7 +39,7 @@ class GaragesaleDetailVm extends _$GaragesaleDetailVm {
 
   GarageDetailState initState() {
     return GarageDetailState(
-        datas: GarageSaleRentDetailEntity()
+        datas: null,
     );
   }
 

+ 7 - 3
packages/cpt_community/lib/modules/garage/garagesale_post/garagesale_post_vm.dart

@@ -5,6 +5,7 @@ import 'package:cpt_community/modules/community/community_vm.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/engine/sp/sp_util.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/http/http_result.dart';
@@ -328,11 +329,11 @@ class GaragesalePostVm extends _$GaragesalePostVm {
 
     String totalContactStr = '';
     if(contactTypeValue == 'Mobile Phone'){
-      totalContactStr = 'mobile:$contactInfoValue)';
+      totalContactStr = 'mobile:$contactInfoValue';
     }else if(contactTypeValue == 'WhatsApp'){
-      totalContactStr = 'whatsapp:$contactInfoValue)';
+      totalContactStr = 'whatsapp:$contactInfoValue';
     }else if(contactTypeValue == 'Email'){
-      totalContactStr = 'email:$contactInfoValue)';
+      totalContactStr = 'email:$contactInfoValue';
     }
 
     // 提交数据
@@ -347,6 +348,9 @@ class GaragesalePostVm extends _$GaragesalePostVm {
     );
 
     if(resResult.isSuccess){
+      // 更新用户信息
+      UserConfigService.getInstance().refreshUserInfo();
+
       final communitVm = ref.read(communityVmProvider.notifier);
       communitVm.getCurrentPageViewVm(null).initPageData();
       // Navigator.pop(context);

+ 4 - 0
packages/cpt_community/lib/modules/my_following/components/item_following_vm.dart

@@ -1,4 +1,5 @@
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 
@@ -42,6 +43,9 @@ class ItemFollowingVm extends _$ItemFollowingVm {
         }else if(itemType == MyFollowingType['isFollowerType']){
           // final myFlowerVm = ref.read(myFollowerVmProvider.notifier);
         }
+
+        // 同步用户信息
+        UserConfigService.getInstance().refreshUserInfo();
         return true;
       }else {
         return false;

+ 19 - 19
packages/cpt_facility/lib/modules/booking/facility_booking_page.dart

@@ -5,6 +5,7 @@ import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:domain/entity/facility_book_entity.dart';
+import 'package:domain/entity/facility_index_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -26,17 +27,16 @@ import 'facility_booking_view_model.dart';
 
 @RoutePage()
 class FacilityBookingPage extends HookConsumerWidget {
-  final String facilityId;
-  final String facilityName;
+  final FacilityIndexEntity facilityEntity;
 
-  const FacilityBookingPage({Key? key, required this.facilityId, required this.facilityName}) : super(key: key);
+  const FacilityBookingPage({Key? key, required this.facilityEntity}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required String facilityId, required String facilityName}) {
+  static void startInstance({BuildContext? context, required FacilityIndexEntity facilityEntity}) {
     if (context != null) {
-      context.router.push(FacilityBookingPageRoute(facilityId: facilityId, facilityName: facilityName));
+      context.router.push(FacilityBookingPageRoute(facilityEntity: facilityEntity));
     } else {
-      appRouter.push(FacilityBookingPageRoute(facilityId: facilityId, facilityName: facilityName));
+      appRouter.push(FacilityBookingPageRoute(facilityEntity: facilityEntity));
     }
   }
 
@@ -48,7 +48,7 @@ class FacilityBookingPage extends HookConsumerWidget {
     useEffect(() {
       // 组件挂载时执行 - 执行接口请求
       Future.microtask(() {
-        viewModel.setFacilityId(facilityId, facilityName);
+        viewModel.setFacilityId(facilityEntity.id, facilityEntity.name);
         viewModel.fetchListByDate();
       });
       return () {
@@ -59,21 +59,20 @@ class FacilityBookingPage extends HookConsumerWidget {
     return Scaffold(
       appBar: MyAppBar.appBar(
         context,
-        facilityName,
+        facilityEntity.name ?? "",
         backgroundColor: context.appColors.backgroundWhite,
         actions: [
           //去设施小区的定位图片
-          const MyAssetImage(
-            Assets.facilityTitleLocationIcon,
-            width: 44,
-            height: 44,
-          ).marginOnly(right: 3).onTap(() {
-            FacilityLocationPage.startInstance(context: context, imageUrls: [
-              "https://mz.eastday.com/63074197.jpeg",
-              "https://t10.baidu.com/it/u=3562774827,189123978&fm=30&app=106&f=PNG?w=640&h=479&s=DFBA6EC80A72B7CC02FC011F0300D0C2",
-              "https://img1.baidu.com/it/u=4090167392,148087489&fm=253&fmt=auto&app=138&f=JPEG?w=484&h=300"
-            ]);
-          }),
+          Visibility(
+            visible: facilityEntity.mapResources.isNotEmpty,
+            child: const MyAssetImage(
+              Assets.facilityTitleLocationIcon,
+              width: 44,
+              height: 44,
+            ).marginOnly(right: 3).onTap(() {
+              FacilityLocationPage.startInstance(context: context, imageUrls: facilityEntity.mapResources);
+            }),
+          )
         ],
       ),
       backgroundColor: context.appColors.backgroundDark,
@@ -121,6 +120,7 @@ class FacilityBookingPage extends HookConsumerWidget {
                 child: MyTextView(
                   S.current.quota_left_msg(state.data?.remainQuota ?? 0, state.data?.quotaResetOn ?? "-"),
                   marginTop: 7,
+                  marginLeft: 10,
                   marginBottom: 15,
                   textColor: context.appColors.textBlack,
                   fontSize: 12,

+ 1 - 1
packages/cpt_facility/lib/modules/booking/facility_booking_view_model.dart

@@ -32,7 +32,7 @@ class FacilityBookingViewModel extends _$FacilityBookingViewModel with DioCancel
   }
 
   //设置设施的ID
-  void setFacilityId(String facilityId, String facilityName) {
+  void setFacilityId(String? facilityId, String? facilityName) {
     state = state.copyWith(facilityId: facilityId, facilityName: facilityName);
   }
 

+ 1 - 1
packages/cpt_facility/lib/modules/booking/facility_booking_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'facility_booking_view_model.dart';
 // **************************************************************************
 
 String _$facilityBookingViewModelHash() =>
-    r'564f4a008b169156b09e3c2325eb1e1cd02e1a47';
+    r'646deef1f63c76e1c0f03d12695d41e0389122d9';
 
 /// See also [FacilityBookingViewModel].
 @ProviderFor(FacilityBookingViewModel)

+ 1 - 1
packages/cpt_facility/lib/modules/detail/facility_detail_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'facility_detail_view_model.dart';
 // **************************************************************************
 
 String _$facilityDetailViewModelHash() =>
-    r'8a361195ada0787beab9b28c38810c95acc51156';
+    r'd026d982cc65cab780f287c0bf91789bc3884202';
 
 /// See also [FacilityDetailViewModel].
 @ProviderFor(FacilityDetailViewModel)

+ 1 - 2
packages/cpt_facility/lib/modules/facility/book/facility_book_screen.dart

@@ -44,8 +44,7 @@ class FacilityBookScreen extends HookConsumerWidget {
                 return FacilityBookItem(index: index, item: state.datas[index]).onTap(() {
                   FacilityBookingPage.startInstance(
                     context: context,
-                    facilityId: state.datas[index].id ?? "",
-                    facilityName: state.datas[index].name ?? "",
+                    facilityEntity: state.datas[index],
                   );
                 });
               },

+ 1 - 1
packages/cpt_facility/lib/modules/facility/book/facility_book_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'facility_book_view_model.dart';
 // **************************************************************************
 
 String _$facilityBookViewModelHash() =>
-    r'a1ae4da61a6245c401083faabca3a6c94b971a4d';
+    r'1424ada4c23a96abadd01134687ecff538650a26';
 
 /// See also [FacilityBookViewModel].
 @ProviderFor(FacilityBookViewModel)

+ 1 - 0
packages/cpt_facility/lib/router/page/facility_page_router.dart

@@ -12,6 +12,7 @@ import '../../modules/detail/facility_detail_page.dart';
 import '../../modules/booking/facility_booking_page.dart';
 import '../../modules/book_confirm/book_confirm_page.dart';
 import '../../modules/location/facility_location_page.dart';
+import 'package:domain/entity/facility_index_entity.dart';
 
 part 'facility_page_router.gr.dart';
 

+ 6 - 12
packages/cpt_facility/lib/router/page/facility_page_router.gr.dart

@@ -39,8 +39,7 @@ abstract class _$FacilityPageRouter extends RootStackRouter {
         routeData: routeData,
         child: FacilityBookingPage(
           key: args.key,
-          facilityId: args.facilityId,
-          facilityName: args.facilityName,
+          facilityEntity: args.facilityEntity,
         ),
       );
     },
@@ -133,15 +132,13 @@ class FacilityBookingPageRoute
     extends PageRouteInfo<FacilityBookingPageRouteArgs> {
   FacilityBookingPageRoute({
     Key? key,
-    required String facilityId,
-    required String facilityName,
+    required FacilityIndexEntity facilityEntity,
     List<PageRouteInfo>? children,
   }) : super(
           FacilityBookingPageRoute.name,
           args: FacilityBookingPageRouteArgs(
             key: key,
-            facilityId: facilityId,
-            facilityName: facilityName,
+            facilityEntity: facilityEntity,
           ),
           initialChildren: children,
         );
@@ -155,19 +152,16 @@ class FacilityBookingPageRoute
 class FacilityBookingPageRouteArgs {
   const FacilityBookingPageRouteArgs({
     this.key,
-    required this.facilityId,
-    required this.facilityName,
+    required this.facilityEntity,
   });
 
   final Key? key;
 
-  final String facilityId;
-
-  final String facilityName;
+  final FacilityIndexEntity facilityEntity;
 
   @override
   String toString() {
-    return 'FacilityBookingPageRouteArgs{key: $key, facilityId: $facilityId, facilityName: $facilityName}';
+    return 'FacilityBookingPageRouteArgs{key: $key, facilityEntity: $facilityEntity}';
   }
 }
 

+ 6 - 6
packages/cpt_main/lib/modules/feedback/feedback_page.dart

@@ -44,8 +44,8 @@ class FeedbackPage extends StatelessWidget {
                     _buildFeedbackCategory(
                       context,
                       Assets.mainFeedbackSend,
-                      45,
-                      51.5,
+                      70,
+                      70,
                       S.current.sent,
                       tabsRouter.activeIndex == 0,
                     ).onTap(
@@ -56,8 +56,8 @@ class FeedbackPage extends StatelessWidget {
                     _buildFeedbackCategory(
                       context,
                       Assets.mainFeedbackInProgress,
-                      48,
-                      46.5,
+                      70,
+                      70,
                       S.current.in_progress,
                       tabsRouter.activeIndex == 1,
                     ).onTap(
@@ -68,8 +68,8 @@ class FeedbackPage extends StatelessWidget {
                     _buildFeedbackCategory(
                       context,
                       Assets.mainFeedbackHistory,
-                      38,
-                      45.5,
+                      70,
+                      70,
                       S.current.history,
                       tabsRouter.activeIndex == 2,
                     ).onTap(

+ 187 - 89
packages/cpt_main/lib/modules/home/home_page.dart

@@ -2,8 +2,10 @@ import 'package:cpt_main/modules/home/home_state.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:domain/entity/home_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
@@ -13,6 +15,7 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
 import 'item_home_category.dart';
 import 'home_view_model.dart';
@@ -20,6 +23,10 @@ import 'item_home_last_news.dart';
 import 'item_home_last_trans.dart';
 import 'item_home_manage_guide.dart';
 import 'item_home_property_news.dart';
+import 'latest_news/info/latest_news_info_screen.dart';
+import 'latest_news/internal/latest_news_internal_screen.dart';
+import 'latest_news/property/latest_news_property_screen.dart';
+import 'latest_news/publish/latest_news_publish_screen.dart';
 
 @RoutePage()
 class HomePage extends HookConsumerWidget {
@@ -29,6 +36,15 @@ class HomePage extends HookConsumerWidget {
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(homeViewModelProvider.notifier);
     final state = ref.watch(homeViewModelProvider);
+    final bannerIndex = useState(0);
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchHomeIndex());
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
 
     return Scaffold(
       appBar: MyAppBar.appBar(context, "Good Afternoon,Mike",
@@ -69,64 +85,67 @@ class HomePage extends HookConsumerWidget {
           ],
           showBottomDivider: true),
       backgroundColor: context.appColors.backgroundDefault,
-      body: CustomScrollView(
-        scrollDirection: Axis.vertical,
-        physics: const BouncingScrollPhysics(),
-        slivers: [
-          //支付与奖励
-          _buildPaymentAndRewardsWidget(context, ref),
-
-          //间距
-          _buildSliverSpace(20),
-
-          //九宫选项组 (固定)
-          _buildCategoryWidget(context, ref),
-
-          //轮播图片 (动态)
-          _buildBannerImage(),
-
-          //最新的新闻(动态)
-          _buildLastNews(context, ref),
-
-          //最新的交易
-          SliverToBoxAdapter(
-            child: MyTextView(
-              marginTop: 14,
-              marginLeft: 15,
-              marginBottom: 14,
-              S.current.latest_transactions,
-              textColor: context.appColors.textPrimary,
-              fontSize: 16,
-              isFontMedium: true,
+      body: EasyRefresh(
+        controller: viewModel.refreshController,
+        onRefresh: viewModel.onRefresh,
+        child: CustomScrollView(
+          scrollDirection: Axis.vertical,
+          slivers: [
+            //支付与奖励
+            _buildPaymentAndRewardsWidget(context, ref),
+
+            //间距
+            _buildSliverSpace(20),
+
+            //九宫选项组 (固定)
+            _buildCategoryWidget(context, ref),
+
+            //轮播图片 (动态)
+            _buildBannerImage(ref, bannerIndex),
+
+            //最新的新闻(动态)
+            _buildLastNews(context, ref),
+
+            //最新的交易
+            SliverToBoxAdapter(
+              child: MyTextView(
+                marginTop: 14,
+                marginLeft: 15,
+                marginBottom: 14,
+                S.current.latest_transactions,
+                textColor: context.appColors.textPrimary,
+                fontSize: 16,
+                isFontMedium: true,
+              ),
             ),
-          ),
 
-          //最新交易列表 (动态)
-          _buildLastTransaction(context, state),
-
-          //房产新闻
-          SliverToBoxAdapter(
-            child: MyTextView(
-              marginTop: 14,
-              marginLeft: 15,
-              marginBottom: 14,
-              onClick: viewModel.gotoPropertyNewsPage,
-              S.current.property_news,
-              textColor: context.appColors.textPrimary,
-              fontSize: 16,
-              isFontMedium: true,
+            //最新交易列表 (动态)
+            _buildLastTransaction(context, state),
+
+            //房产新闻
+            SliverToBoxAdapter(
+              child: MyTextView(
+                marginTop: 14,
+                marginLeft: 15,
+                marginBottom: 14,
+                onClick: viewModel.gotoPropertyNewsPage,
+                S.current.property_news,
+                textColor: context.appColors.textPrimary,
+                fontSize: 16,
+                isFontMedium: true,
+              ),
             ),
-          ),
 
-          //房产新闻列表 (动态)
-          _buildPropertyNews(context, state),
+            //房产新闻列表 (动态)
+            _buildPropertyNews(context, ref),
 
-          //管理员介绍 (固定)
-          _buildManagementGuides(context, ref),
+            //管理员介绍 (固定)
+            _buildManagementGuides(context, ref),
 
-          //间距
-          _buildSliverSpace(15),
-        ],
+            //间距
+            _buildSliverSpace(15),
+          ],
+        ),
       ),
     );
   }
@@ -221,16 +240,75 @@ class HomePage extends HookConsumerWidget {
   }
 
   //Banner的布局
-  Widget _buildBannerImage() {
+  Widget _buildBannerImage(WidgetRef ref, ValueNotifier<int> bannerIndex) {
+    final viewModel = ref.read(homeViewModelProvider.notifier);
+    final state = ref.watch(homeViewModelProvider);
+
     return SliverToBoxAdapter(
-      child: Center(
-        child: MyLoadImage(
-          "https://t11.baidu.com/it/u=1326770860,192430039&fm=30&app=106&f=JPEG?w=640&h=427&s=33B5BFAA6A165BCA182937620300D077",
-          width: 345,
-          height: 152.5,
-          cornerRadius: 5,
-        ),
-      ).marginOnly(top: 21),
+      child: Container(
+        width: double.infinity,
+        margin: const EdgeInsets.only(top: 21, left: 15, right: 15),
+        child: state.homeIndex != null && state.homeIndex!.banners.isNotEmpty
+            ? Stack(
+                alignment: Alignment.bottomCenter, // 设置 Stack 的对齐方式为底部中心
+                children: [
+                  CarouselSlider(
+                    options: CarouselOptions(
+                      aspectRatio: 345 / 152.5,
+                      viewportFraction: 1,
+                      initialPage: 0,
+                      enableInfiniteScroll: true,
+                      reverse: false,
+                      autoPlay: true,
+                      autoPlayInterval: const Duration(seconds: 5),
+                      autoPlayAnimationDuration: const Duration(milliseconds: 800),
+                      autoPlayCurve: Curves.fastOutSlowIn,
+                      enlargeCenterPage: true,
+                      scrollDirection: Axis.horizontal,
+                      onPageChanged: (index, reason) {
+                        bannerIndex.value = index;
+                      },
+                    ),
+                    items: state.homeIndex!.banners.map<Widget>((item) {
+                      return MyLoadImage(
+                        item.image,
+                        width: double.infinity,
+                        cornerRadius: 5,
+                      );
+                    }).toList(),
+                  ),
+                  Positioned(
+                    bottom: 10, // 距离底部 20 像素
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: state.homeIndex!.banners.map((item) {
+                        //难道就没有indexMap,要么就转换为Map的方式进行遍历Map
+                        int index = state.homeIndex!.banners.indexOf(item);
+                        return Container(
+                          width: 6.5,
+                          height: 6.5,
+                          margin: const EdgeInsets.symmetric(horizontal: 3.5),
+                          decoration: BoxDecoration(
+                            shape: BoxShape.circle,
+                            color: bannerIndex.value == index
+                                ? const Color(0x4D000000) // 选中状态颜色
+                                : const Color(0x1A000000), // 未选中状态颜色
+                          ),
+                        );
+                      }).toList(),
+                    ),
+                  ),
+                ],
+              )
+            : AspectRatio(
+                aspectRatio: 345 / 152.5,
+                child: MyLoadImage(
+                  Assets.baseLibImageDefaultPlaceholder,
+                  width: double.infinity,
+                  cornerRadius: 5,
+                ),
+              ),
+      ),
     );
   }
 
@@ -253,18 +331,29 @@ class HomePage extends HookConsumerWidget {
           onClick: viewModel.gotoLastNewsPage,
           textColor: context.appColors.textPrimary,
         ),
-        SingleChildScrollView(
-          scrollDirection: Axis.horizontal,
-          physics: const BouncingScrollPhysics(),
-          clipBehavior: Clip.none,
-          child: Row(
-            children: List.generate(state.lastNews.length, (index) {
-              return LastNewsItem(
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceAround, // 均匀排布
+          children: List.generate(state.lastNews.length, (index) {
+            return Expanded(
+              // 使用 Expanded 使每个子项占据相同空间
+              child: LastNewsItem(
                 lastNews: state.lastNews[index],
-              );
-            }),
-          ),
-        )
+                onItemTap: () {
+                  //根据不同的索引跳转到不同的PageView指定页面
+                  if (index == 0) {
+                    LatestNewsPropertyScreen.startInstance(context: context);
+                  } else if (index == 1) {
+                    LatestNewsInternalScreen.startInstance(context: context);
+                  } else if (index == 2) {
+                    LatestNewsInfoScreen.startInstance(context: context);
+                  } else if (index == 3) {
+                    LatestNewsPublishScreen.startInstance(context: context);
+                  }
+                },
+              ),
+            );
+          }),
+        ),
       ],
     ).paddingOnly(left: 15, right: 15));
   }
@@ -294,11 +383,11 @@ class HomePage extends HookConsumerWidget {
                 return Padding(
                   padding: const EdgeInsets.symmetric(vertical: 10),
                   child: LastTransItem(
-                    lastTrans: state.lastTrans[index],
+                    lastTrans: state.homeIndex!.latestTransactions[index],
                   ),
                 );
               },
-              childCount: state.lastTrans.length,
+              childCount: state.homeIndex?.latestTransactions.length ?? 0,
             ),
           ),
         ),
@@ -307,33 +396,40 @@ class HomePage extends HookConsumerWidget {
   }
 
   //房产新闻的双列表
-  Widget _buildPropertyNews(BuildContext context, HomeState state) {
+  Widget _buildPropertyNews(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(homeViewModelProvider);
+    final propertyNewsList = state.homeIndex?.propertyNews ?? [];
+
+    // 计算行数和每行的元素
+    int totalItems = propertyNewsList.length;
+    int firstRowCount = (totalItems + 1) ~/ 2; // 第1行的数量 (奇数时多一个)
+    int secondRowCount = totalItems ~/ 2; // 第2行的数量
+
     return SliverList(
       delegate: SliverChildListDelegate(
         [
-          // PropertyNews(),
-
           // 第一个水平滑动列表
-          _buildPropertyNewsHorizontalList(),
+          _buildPropertyNewsHorizontalList(propertyNewsList.sublist(0, firstRowCount)),
 
           const SizedBox(height: 10),
 
-          // // 第二个水平滑动列表
-          _buildPropertyNewsHorizontalList(),
+          // 第二个水平滑动列表
+          if (secondRowCount > 0) // 只有在有第二行内容时才显示
+            _buildPropertyNewsHorizontalList(propertyNewsList.sublist(firstRowCount, firstRowCount + secondRowCount)),
         ],
       ),
     );
   }
 
-  Widget _buildPropertyNewsHorizontalList() {
+  Widget _buildPropertyNewsHorizontalList(List<HomeListPropertyNews> propertyNews) {
     return SingleChildScrollView(
       scrollDirection: Axis.horizontal,
       physics: const BouncingScrollPhysics(),
       clipBehavior: Clip.none,
       child: Row(
-        children: List.generate(5, (index) {
-          return PropertyNews();
-        }),
+        children: propertyNews.map((news) {
+          return PropertyNews(news: news); // 假设 PropertyNews 需要传入一个 news 参数
+        }).toList(),
       ).marginOnly(left: 15, right: 15),
     );
   }
@@ -362,11 +458,13 @@ class HomePage extends HookConsumerWidget {
           physics: const BouncingScrollPhysics(),
           clipBehavior: Clip.none,
           child: Row(
-            children: List.generate(state.manage_guide.length, (index) {
-              return ManageGuideItem(
-                manageGuide: state.manage_guide[index],
-              );
-            }),
+            children: state.homeIndex?.strataManagementGuides == null
+                ? [const SizedBox.shrink()]
+                : List.generate(state.homeIndex!.strataManagementGuides.length, (index) {
+                    return ManageGuideItem(
+                      manageGuide: state.homeIndex!.strataManagementGuides[index],
+                    );
+                  }),
           ),
         )
       ],

+ 75 - 96
packages/cpt_main/lib/modules/home/home_state.dart

@@ -1,103 +1,82 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/home_list_entity.dart';
 
 class HomeState {
-  final homeCategory = [
-    {
-      'category_name': S.current.facility,
-      'category_icon': Assets.mainHomeFacilityIcon,
-    },
-    {
-      'category_name': S.current.form,
-      'category_icon': Assets.mainHomeFormsIcon,
-    },
-    {
-      'category_name': S.current.notice_board,
-      'category_icon': Assets.mainHomeBoticeBoardIcon,
-    },
-    {
-      'category_name': S.current.property,
-      'category_icon': Assets.mainHomePropertyIcon,
-    },
-    {
-      'category_name': S.current.service,
-      'category_icon': Assets.mainHomeServiceIcon,
-    },
-    {
-      'category_name': S.current.community,
-      'category_icon': Assets.mainHomeCommunityIcon,
-    }
-  ];
+  final List<Map<String, dynamic>> homeCategory;
+  final List<Map<String, dynamic>> lastNews;
+  HomeListEntity? homeIndex;
 
-  final lastNews = [
-    {
-      'category_name': S.current.property,
-      'category_icon': Assets.mainHomePropertyNews,
-      'icon_width': 38.5,
-      'icon_height': 39.5,
-      'margin_right': 13.0,
-    },
-    {
-      'category_name': S.current.internal,
-      'category_icon': Assets.mainHomeInternalNews,
-      'icon_width': 33.5,
-      'icon_height': 41.0,
-      'margin_right': 11.0,
-    },
-    {
-      'category_name': S.current.info,
-      'category_icon': Assets.mainHomeInfoNews,
-      'icon_width': 44.0,
-      'icon_height': 42.0,
-      'margin_right': 6.0,
-    },
-    {
-      'category_name': S.current.publish,
-      'category_icon': Assets.mainHomePublishNews,
-      'icon_width': 40.5,
-      'icon_height': 42.5,
-      'margin_right': 11.0,
-    }
-  ];
+  HomeState({
+    List<Map<String, dynamic>>? homeCategory,
+    List<Map<String, dynamic>>? lastNews,
+    this.homeIndex,
+  })  : homeCategory = homeCategory ??
+            [
+              {
+                'category_name': S.current.facility,
+                'category_icon': Assets.mainHomeFacilityIcon,
+              },
+              {
+                'category_name': S.current.form,
+                'category_icon': Assets.mainHomeFormsIcon,
+              },
+              {
+                'category_name': S.current.notice_board,
+                'category_icon': Assets.mainHomeBoticeBoardIcon,
+              },
+              {
+                'category_name': S.current.property,
+                'category_icon': Assets.mainHomePropertyIcon,
+              },
+              {
+                'category_name': S.current.service,
+                'category_icon': Assets.mainHomeServiceIcon,
+              },
+              {
+                'category_name': S.current.community,
+                'category_icon': Assets.mainHomeCommunityIcon,
+              }
+            ],
+        lastNews = lastNews ??
+            [
+              {
+                'category_name': S.current.property,
+                'category_icon': Assets.mainHomePropertyNews,
+                'icon_width': 38.5,
+                'icon_height': 39.5,
+                'margin_right': 13.0,
+              },
+              {
+                'category_name': S.current.internal,
+                'category_icon': Assets.mainHomeInternalNews,
+                'icon_width': 33.5,
+                'icon_height': 41.0,
+                'margin_right': 11.0,
+              },
+              {
+                'category_name': S.current.info,
+                'category_icon': Assets.mainHomeInfoNews,
+                'icon_width': 44.0,
+                'icon_height': 42.0,
+                'margin_right': 6.0,
+              },
+              {
+                'category_name': S.current.notice,
+                'category_icon': Assets.mainHomePublishNews,
+                'icon_width': 40.5,
+                'icon_height': 42.5,
+                'margin_right': 11.0,
+              }
+            ];
 
-
-  final manage_guide = [
-    {
-      'category_name': S.current.introduction_to_info_pack,
-      'category_icon': Assets.mainIntroductionGuide,
-      'icon_width': 118.5,
-      'icon_height': 73.5,
-      'margin_top': 12.0,
-    },
-    {
-      'category_name': S.current.your_roles_responsibilities,
-      'category_icon': Assets.mainRolesGuide,
-      'icon_width': 116,
-      'icon_height': 78,
-      'margin_top': 8.5,
-    },
-    {
-      'category_name': S.current.property_guide,
-      'category_icon': Assets.mainPropertyGuide,
-      'icon_width': 117.0,
-      'icon_height': 76.5,
-      'margin_top': 10.0,
-    },
-  ];
-
-  //模拟数据
-  final lastTrans = [
-    {
-      'title': '18 Sep 2024 Blk 39 #09-XX',
-      'price': '1,001 - 1,337 sqft',
-      'total': '1.338 M',
-      'unit': '',
-    },
-    {
-      'title': 'Jul 2024  Blk XX #XX to XX',
-      'price': '1,100 - 1,200 sqft',
-      'total': '4,000 M',
-      'unit': 'per month',
-    },
-  ];
+  HomeState copyWith({
+    HomeListEntity? homeIndex,
+  }) {
+    return HomeState(
+      homeIndex: homeIndex ?? this.homeIndex,
+      homeCategory: homeCategory,
+      lastNews: lastNews,
+    );
+  }
 }

+ 43 - 3
packages/cpt_main/lib/modules/home/home_view_model.dart

@@ -1,9 +1,11 @@
 import 'package:cpt_main/modules/home/property_news/home_property_news_page.dart';
 import 'package:cpt_main/modules/notification/notification_page.dart';
+import 'package:domain/repository/main_repository.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:router/componentRouter/community_service.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
+import 'package:widgets/widget_export.dart';
 
 import 'home_state.dart';
 import 'latest_news/latest_news_page.dart';
@@ -12,10 +14,47 @@ import 'management_guides/management_guides_page.dart';
 part 'home_view_model.g.dart';
 
 @riverpod
-class HomeViewModel extends _$HomeViewModel {
+class HomeViewModel extends _$HomeViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
+  var _needShowLoading = true; //是否展示LoadingView
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: false, //允许加载
+  );
+
   @override
   HomeState build() {
-    return HomeState();
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = HomeState();
+    registerCancellation();
+    return state;
+  }
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    fetchHomeIndex();
+  }
+
+  /// 获取首页数据
+  Future fetchHomeIndex() async {
+    // 获取列表
+    var result = await _mainRepository.fetchHomeIndex(
+      needLoading: _needShowLoading,
+      cancelToken: cancelToken,
+    );
+
+    // 处理数据
+    if (result.isSuccess) {
+      state = state.copyWith(homeIndex: result.data);
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+
+    // 最后赋值
+    _needShowLoading = false;
+    refreshController.finishRefresh();
   }
 
   /// 根据索引触发点击的事件
@@ -72,4 +111,5 @@ class HomeViewModel extends _$HomeViewModel {
   void gotoManageGuidePage() {
     ManagementGuidesPage.startInstance();
   }
+
 }

+ 4 - 2
packages/cpt_main/lib/modules/home/item_home_last_news.dart

@@ -7,8 +7,9 @@ import 'package:widgets/my_text_view.dart';
 
 class LastNewsItem extends StatelessWidget {
   final Map<String, dynamic> lastNews;
+  void Function() onItemTap;
 
-  LastNewsItem({required this.lastNews});
+  LastNewsItem({required this.lastNews, required this.onItemTap});
 
   @override
   Widget build(BuildContext context) {
@@ -55,6 +56,7 @@ class LastNewsItem extends StatelessWidget {
           ],
         )
         .marginOnly(right: 5)
-        .constrained(width: 86.5, height: 78.5);
+        .constrained(width: 86.5, height: 78.5)
+        .onTap(onItemTap);
   }
 }

+ 16 - 15
packages/cpt_main/lib/modules/home/item_home_last_trans.dart

@@ -1,5 +1,6 @@
 import 'package:cpt_main/modules/feedback/feedback_page.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/home_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
@@ -7,7 +8,7 @@ import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
 class LastTransItem extends StatelessWidget {
-  final Map<String, dynamic> lastTrans;
+  HomeListLatestTransactions lastTrans;
 
   LastTransItem({required this.lastTrans});
 
@@ -22,13 +23,13 @@ class LastTransItem extends StatelessWidget {
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             MyTextView(
-              lastTrans['title'],
+              lastTrans.title ?? "",
               fontSize: 15,
               textColor: context.appColors.textBlack,
               isFontMedium: true,
             ),
             MyTextView(
-              lastTrans['price'],
+              lastTrans.price ?? "",
               fontSize: 15,
               marginTop: 5,
               textColor: context.appColors.textBlack,
@@ -36,10 +37,9 @@ class LastTransItem extends StatelessWidget {
             ),
           ],
         ).expanded(),
-
         Container(
-          width: 91.5,
           margin: const EdgeInsets.only(left: 10),
+          padding: const EdgeInsets.symmetric(horizontal: 5),
           height: 45,
           decoration: BoxDecoration(
             color: context.appColors.lightPurpleBg,
@@ -50,22 +50,23 @@ class LastTransItem extends StatelessWidget {
             mainAxisAlignment: MainAxisAlignment.center,
             children: [
               MyTextView(
-               "\$${lastTrans['total']}",
+                "\$${lastTrans.price ?? "-"}",
                 fontSize: 17,
                 textColor: context.appColors.textBlack,
                 isFontMedium: true,
               ),
-              Visibility(
-                  visible: Utils.isNotEmpty(lastTrans['unit']),
-                  child: MyTextView(
-                    lastTrans['unit'],
-                    fontSize: 12,
-                    textColor: context.appColors.textBlack,
-                    isFontRegular: true,
-                  ))
+              //单元,每个月或者没有单元
+              // Visibility(
+              //     visible: Utils.isNotEmpty(lastTrans['unit']),
+              //     child: MyTextView(
+              //       lastTrans['unit'],
+              //       fontSize: 12,
+              //       textColor: context.appColors.textBlack,
+              //       isFontRegular: true,
+              //     ))
             ],
           ),
-        ),
+        ).constrained(minWidth: 92),
       ],
     );
   }

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

@@ -1,12 +1,13 @@
 import 'package:cpt_main/modules/feedback/feedback_page.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/home_list_entity.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 ManageGuideItem extends StatelessWidget {
-  final Map<String, dynamic> manageGuide;
+  HomeListPropertyNews manageGuide;
 
   ManageGuideItem({required this.manageGuide});
 
@@ -16,15 +17,12 @@ class ManageGuideItem extends StatelessWidget {
       crossAxisAlignment: CrossAxisAlignment.start,
       mainAxisAlignment: MainAxisAlignment.start,
       children: [
-        MyAssetImage(
-          manageGuide['category_icon'],
-          width: (manageGuide['icon_width'] as num).toDouble(),
-          height: (manageGuide['icon_height'] as num).toDouble(),
-          fit: BoxFit.cover, // 调整 fit 参数
-        ).marginOnly(top: manageGuide['margin_top']),
-
+        MyLoadImage(
+          manageGuide.coverImage,
+          fit: BoxFit.contain,
+        ).marginOnly(top: 10),
         MyTextView(
-          manageGuide['category_name'],
+          manageGuide.title ?? "",
           marginLeft: 9,
           marginTop: 10,
           maxLines: 2,

+ 6 - 3
packages/cpt_main/lib/modules/home/item_home_property_news.dart

@@ -1,5 +1,6 @@
 import 'package:cpt_main/modules/feedback/feedback_page.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/home_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
@@ -7,7 +8,9 @@ import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
 class PropertyNews extends StatelessWidget {
-  PropertyNews();
+  final HomeListPropertyNews? news;
+
+  PropertyNews({required this.news});
 
   @override
   Widget build(BuildContext context) {
@@ -16,12 +19,12 @@ class PropertyNews extends StatelessWidget {
       mainAxisAlignment: MainAxisAlignment.start,
       children: [
         MyLoadImage(
-          "https://t11.baidu.com/it/u=4142771387,220552469&fm=30&app=106&f=JPEG?w=564&h=604&s=FA2FB04406270B0D68AE05910300509B",
+          news?.coverImage,
           width: 80,
           height: 80,
         ),
         MyTextView(
-          "Key Appeals and Performance of Nonlan-ded Properties in District 19",
+          news?.title ?? "",
           fontSize: 15,
           marginLeft: 12.5,
           marginRight: 12.5,

+ 18 - 6
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_screen.dart

@@ -1,18 +1,28 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../item_latest_news.dart';
 import 'latest_news_info_view_model.dart';
 
-
 @RoutePage()
 class LatestNewsInfoScreen extends HookConsumerWidget {
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const LatestNewsInfoPageRoute());
+    } else {
+      appRouter.push(const LatestNewsInfoPageRoute());
+    }
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(latestNewsInfoViewModelProvider.notifier);
@@ -42,11 +52,13 @@ class LatestNewsInfoScreen extends HookConsumerWidget {
           successSliverWidget: [
             SliverList(
                 delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                    return ListNewsItem(index: index, item: state.datas[index]);
-                  },
-                  childCount: state.datas.length,
-                ))
+              (context, index) {
+                return LatestNewsItem(index: index, item: state.datas[index]).onTap((){
+                  viewModel.gotoLatestNewsDetail(context,state.datas[index]);
+                });
+              },
+              childCount: state.datas.length,
+            ))
           ],
         ),
       ).marginOnly(top: 5, bottom: 5),

+ 3 - 2
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_state.dart

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

+ 64 - 70
packages/cpt_main/lib/modules/home/latest_news/info/latest_news_info_view_model.dart

@@ -1,3 +1,10 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/modules/global_web_page.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,19 +15,23 @@ import 'latest_news_info_state.dart';
 part 'latest_news_info_view_model.g.dart';
 
 @riverpod
-class LatestNewsInfoViewModel extends _$LatestNewsInfoViewModel {
+class LatestNewsInfoViewModel extends _$LatestNewsInfoViewModel with DioCancelableMixin{
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   LatestNewsInfoState build() {
-    return LatestNewsInfoState(datas: []);
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = LatestNewsInfoState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -53,44 +64,18 @@ class LatestNewsInfoViewModel extends _$LatestNewsInfoViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
-
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
+    // 获取列表
+    var listResult = await _mainRepository.fetchLatestNewsList(
+      type: "3",
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-      state = state.copyWith(datas: allList);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -98,33 +83,42 @@ class LatestNewsInfoViewModel extends _$LatestNewsInfoViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<LatestNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<LatestNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  /// 去详情页面
+  void gotoLatestNewsDetail(BuildContext context, LatestNewsList data) async {
+    final result = await _mainRepository.fetchLatestNewsDetail(id: data.id ?? "");
+    if (result.isSuccess) {
+      GlobalWebPage.startInstance(context: context, title: S.current.latest_news, url: result.data?.content ?? "");
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+  }
+
 }

+ 15 - 1
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_screen.dart

@@ -1,17 +1,29 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../item_latest_news.dart';
 import 'latest_news_internal_view_model.dart';
 
 
 @RoutePage()
 class LatestNewsInternalScreen extends HookConsumerWidget {
+
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const LatestNewsInternalPageRoute());
+    } else {
+      appRouter.push(const LatestNewsInternalPageRoute());
+    }
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(latestNewsInternalViewModelProvider.notifier);
@@ -42,7 +54,9 @@ class LatestNewsInternalScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return ListNewsItem(index: index, item: state.datas[index]);
+                        return LatestNewsItem(index: index, item: state.datas[index]).onTap((){
+                          viewModel.gotoLatestNewsDetail(context,state.datas[index]);
+                        });
                   },
                   childCount: state.datas.length,
                 ))

+ 3 - 2
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_state.dart

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

+ 64 - 71
packages/cpt_main/lib/modules/home/latest_news/internal/latest_news_internal_view_model.dart

@@ -1,5 +1,11 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/modules/global_web_page.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
@@ -8,19 +14,23 @@ import 'latest_news_internal_state.dart';
 part 'latest_news_internal_view_model.g.dart';
 
 @riverpod
-class LatestNewsInternalViewModel extends _$LatestNewsInternalViewModel {
+class LatestNewsInternalViewModel extends _$LatestNewsInternalViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   LatestNewsInternalState build() {
-    return LatestNewsInternalState(datas: []);
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = LatestNewsInternalState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -53,44 +63,18 @@ class LatestNewsInternalViewModel extends _$LatestNewsInternalViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
-
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
+    // 获取列表
+    var listResult = await _mainRepository.fetchLatestNewsList(
+      type: "2",
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-      state = state.copyWith(datas: allList);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -98,33 +82,42 @@ class LatestNewsInternalViewModel extends _$LatestNewsInternalViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<LatestNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<LatestNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  /// 去详情页面
+  void gotoLatestNewsDetail(BuildContext context, LatestNewsList data) async {
+    final result = await _mainRepository.fetchLatestNewsDetail(id: data.id ?? "");
+    if (result.isSuccess) {
+      GlobalWebPage.startInstance(context: context, title: S.current.latest_news, url: result.data?.content ?? "");
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+  }
+
 }

+ 84 - 0
packages/cpt_main/lib/modules/home/latest_news/item_latest_news.dart

@@ -0,0 +1,84 @@
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+///  首页最新新闻News 的Item
+class LatestNewsItem extends StatelessWidget {
+  final int index;
+  final LatestNewsList item;
+
+  const LatestNewsItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      height: 117.5,
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteBG,
+        borderRadius: BorderRadius.circular(6.0), // 圆角
+        boxShadow: [
+          BoxShadow(
+            color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+            offset: const Offset(0, 3), // 阴影的偏移量
+            blurRadius: 8.0, // 模糊半径
+            spreadRadius: 3.0, // 扩散半径
+          ),
+        ],
+      ),
+      child: Row(
+        mainAxisSize: MainAxisSize.max,
+        children: [
+          MyLoadImage(
+            item.coverImage,
+            width: 100,
+            height: 117.5,
+          ).marginOnly(right: 18),
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //标题
+              MyTextView(
+                item.title??"",
+                marginTop: 12,
+                fontSize: 16,
+                maxLines: 2,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+
+              //内容
+              MyTextView(
+                item.content??"",
+                marginTop: 5,
+                fontSize: 12,
+                maxLines: 2,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+
+              const Spacer(),
+
+              //时间
+              MyTextView(
+                item.createdAt??"",
+                fontSize: 12,
+                marginBottom: 12,
+                marginTop: 12,
+                textColor: context.appColors.textBlack,
+                isFontRegular: true,
+              ),
+            ],
+          ).expanded(),
+        ],
+      ),
+    );
+  }
+}

+ 15 - 2
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_screen.dart

@@ -1,17 +1,28 @@
 import 'package:auto_route/auto_route.dart';
-import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../item_latest_news.dart';
 import 'latest_news_property_view_model.dart';
 
 
 @RoutePage()
 class LatestNewsPropertyScreen extends HookConsumerWidget {
+
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const LatestNewsPropertyPageRoute());
+    } else {
+      appRouter.push(const LatestNewsPropertyPageRoute());
+    }
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(latestNewsPropertyViewModelProvider.notifier);
@@ -42,7 +53,9 @@ class LatestNewsPropertyScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return ListNewsItem(index: index, item: state.datas[index]);
+                        return LatestNewsItem(index: index, item: state.datas[index]).onTap((){
+                          viewModel.gotoLatestNewsDetail(context,state.datas[index]);
+                        });
                   },
                   childCount: state.datas.length,
                 ))

+ 3 - 2
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_state.dart

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

+ 62 - 69
packages/cpt_main/lib/modules/home/latest_news/property/latest_news_property_view_model.dart

@@ -1,3 +1,10 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/modules/global_web_page.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,19 +15,22 @@ import 'latest_news_property_state.dart';
 part 'latest_news_property_view_model.g.dart';
 
 @riverpod
-class LatestNewsPropertyViewModel extends _$LatestNewsPropertyViewModel {
+class LatestNewsPropertyViewModel extends _$LatestNewsPropertyViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   LatestNewsPropertyState build() {
+    _mainRepository = ref.read(mainRepositoryProvider);
     final state = LatestNewsPropertyState(datas: []);
+    registerCancellation();
     return state;
   }
 
@@ -54,44 +64,18 @@ class LatestNewsPropertyViewModel extends _$LatestNewsPropertyViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
-
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
+    // 获取列表
+    var listResult = await _mainRepository.fetchLatestNewsList(
+      type: "1",
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-      state = state.copyWith(datas: allList);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -99,33 +83,42 @@ class LatestNewsPropertyViewModel extends _$LatestNewsPropertyViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<LatestNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<LatestNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  /// 去详情页面
+  void gotoLatestNewsDetail(BuildContext context, LatestNewsList data) async {
+    final result = await _mainRepository.fetchLatestNewsDetail(id: data.id ?? "");
+    if (result.isSuccess) {
+      GlobalWebPage.startInstance(context: context, title: S.current.latest_news, url: result.data?.content ?? "");
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+  }
+
 }

+ 19 - 6
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_screen.dart

@@ -1,17 +1,28 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:cpt_main/modules/home/property_news/item_list_news.dart';
+import 'package:cpt_main/router/page/main_page_router.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../item_latest_news.dart';
 import 'latest_news_publish_view_model.dart';
 
-
 @RoutePage()
 class LatestNewsPublishScreen extends HookConsumerWidget {
+
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const LatestNewsPublishPageRoute());
+    } else {
+      appRouter.push(const LatestNewsPublishPageRoute());
+    }
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final viewModel = ref.read(latestNewsPublishViewModelProvider.notifier);
@@ -41,11 +52,13 @@ class LatestNewsPublishScreen extends HookConsumerWidget {
           successSliverWidget: [
             SliverList(
                 delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                    return ListNewsItem(index: index, item: state.datas[index]);
-                  },
-                  childCount: state.datas.length,
-                ))
+              (context, index) {
+                return LatestNewsItem(index: index, item: state.datas[index]).onTap((){
+                  viewModel.gotoLatestNewsDetail(context,state.datas[index]);
+                });
+              },
+              childCount: state.datas.length,
+            ))
           ],
         ),
       ).marginOnly(top: 5, bottom: 5),

+ 3 - 2
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_state.dart

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

+ 64 - 70
packages/cpt_main/lib/modules/home/latest_news/publish/latest_news_publish_view_model.dart

@@ -1,3 +1,10 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/modules/global_web_page.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,19 +15,23 @@ import 'latest_news_publish_state.dart';
 part 'latest_news_publish_view_model.g.dart';
 
 @riverpod
-class LatestNewsPublishViewModel extends _$LatestNewsPublishViewModel {
+class LatestNewsPublishViewModel extends _$LatestNewsPublishViewModel with DioCancelableMixin{
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   LatestNewsPublishState build() {
-    return LatestNewsPublishState(datas: []);
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = LatestNewsPublishState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -53,44 +64,18 @@ class LatestNewsPublishViewModel extends _$LatestNewsPublishViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
-
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
+    // 获取列表
+    var listResult = await _mainRepository.fetchLatestNewsList(
+      type: "4",
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-      state = state.copyWith(datas: allList);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -98,33 +83,42 @@ class LatestNewsPublishViewModel extends _$LatestNewsPublishViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<LatestNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<LatestNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  /// 去详情页面
+  void gotoLatestNewsDetail(BuildContext context, LatestNewsList data) async {
+    final result = await _mainRepository.fetchLatestNewsDetail(id: data.id ?? "");
+    if (result.isSuccess) {
+      GlobalWebPage.startInstance(context: context, title: S.current.latest_news, url: result.data?.content ?? "");
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+  }
+
 }

+ 6 - 7
packages/cpt_main/lib/modules/home/management_guides/item_management_guide.dart

@@ -1,16 +1,15 @@
 import 'package:cpt_main/modules/feedback/feedback_page.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
 class ManagementGuideItem extends StatelessWidget {
-  final String? iconImage;
-  final String? title;
+  final LatestNewsList? item;
 
   ManagementGuideItem({
-    this.iconImage,
-    this.title,
+    this.item,
   });
 
   @override
@@ -34,14 +33,14 @@ class ManagementGuideItem extends StatelessWidget {
         children: [
           AspectRatio(
             aspectRatio: 165 / 108, // 设置宽高比例为 165:108
-            child: MyAssetImage(
-              iconImage ?? "-",
+            child: MyLoadImage(
+              item?.coverImage,
               width: double.infinity,
               height: double.infinity,
             ),
           ),
           MyTextView(
-            title ?? "-",
+            item?.title ?? "-",
             marginLeft: 9,
             marginTop: 15,
             maxLines: 2,

+ 4 - 3
packages/cpt_main/lib/modules/home/management_guides/management_guides_page.dart

@@ -67,9 +67,10 @@ class ManagementGuidesPage extends HookConsumerWidget {
                   delegate: SliverChildBuilderDelegate(
                         (BuildContext context, int index) {
                       return ManagementGuideItem(
-                        iconImage: state.datas[index].iconImage,
-                        title: state.datas[index].title,
-                      ); // 生成每个网格项
+                       item: state.datas[index],
+                      ).onTap((){
+                        viewModel.gotoLatestNewsDetail(context, state.datas[index]);
+                      }); // 生成每个网格项
                     },
                     childCount: state.datas.length, // 总共的网格项数
                   ),

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

@@ -1,4 +1,4 @@
-import 'package:cpt_main/modules/home/management_guides/test_guide_bean.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class ManagementGuidesState {
@@ -7,7 +7,7 @@ class ManagementGuidesState {
   LoadState loadingState;
   String? errorMessage;
 
-  List<TestGuideBean> datas; //页面列表数据
+  List<LatestNewsList> datas; //页面列表数据
 
   // ===================================  Begin  ↓  ===================================
 
@@ -21,7 +21,7 @@ class ManagementGuidesState {
     LoadState? loadingState,
     String? errorMessage,
     bool? needShowPlaceholder,
-    List<TestGuideBean>? datas,
+    List<LatestNewsList>? datas,
   }) {
     return ManagementGuidesState(
       errorMessage: errorMessage ?? this.errorMessage,

+ 59 - 81
packages/cpt_main/lib/modules/home/management_guides/management_guides_view_model.dart

@@ -1,17 +1,22 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/latest_news_page_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/modules/global_web_page.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
 import 'management_guides_state.dart';
-import 'test_guide_bean.dart';
 
 part 'management_guides_view_model.g.dart';
 
 @riverpod
-class ManagementGuidesViewModel extends _$ManagementGuidesViewModel {
+class ManagementGuidesViewModel extends _$ManagementGuidesViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
@@ -23,7 +28,10 @@ class ManagementGuidesViewModel extends _$ManagementGuidesViewModel {
 
   @override
   ManagementGuidesState build() {
-    return ManagementGuidesState(datas: []);
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = ManagementGuidesState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -56,55 +64,17 @@ class ManagementGuidesViewModel extends _$ManagementGuidesViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<TestGuideBean> list = [
-      TestGuideBean()
-        ..iconImage = Assets.mainIntroductionGuide
-        ..title = S.current.introduction_to_info_pack,
-
-      TestGuideBean()
-        ..iconImage = Assets.mainRolesGuide
-        ..title = S.current.your_roles_responsibilities,
-
-      TestGuideBean()
-        ..iconImage = Assets.mainPropertyGuide
-        ..title = S.current.property_guide,
-    ];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
-    } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
+    // 获取列表
+    var listResult = await _mainRepository.fetchManageGuideList(
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-      state = state.copyWith(datas: allList);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -112,33 +82,41 @@ class ManagementGuidesViewModel extends _$ManagementGuidesViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<LatestNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<LatestNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  /// 去详情页面
+  void gotoLatestNewsDetail(BuildContext context, LatestNewsList data) async {
+    final result = await _mainRepository.fetchManageGuideDetail(id: data.id ?? "");
+    if (result.isSuccess) {
+      GlobalWebPage.startInstance(context: context, title: S.current.latest_news, url: result.data?.content ?? "");
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    }
+  }
 }

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

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

+ 5 - 2
packages/cpt_main/lib/modules/home/property_news/home_property_news_page.dart

@@ -5,6 +5,7 @@ import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
@@ -17,7 +18,6 @@ import 'home_property_news_view_model.dart';
 
 @RoutePage()
 class HomePropertyNewsPage extends HookConsumerWidget {
-
   static void startInstance({BuildContext? context}) {
     if (context != null) {
       context.router.push(const HomePropertyNewsPageRoute());
@@ -59,7 +59,10 @@ class HomePropertyNewsPage extends HookConsumerWidget {
               SliverList(
                   delegate: SliverChildBuilderDelegate(
                 (context, index) {
-                  return ListNewsItem(index: index, item: state.datas[index]);
+                  return ListNewsItem(index: index, item: state.datas[index]).onTap(() {
+                    //路由跳转到Property模块的新闻详情页面
+                    ComponentServiceManager().propertyService.startPropertyNewsDetailPage(state.datas[index].id ?? 0);
+                  });
                 },
                 childCount: state.datas.length,
               ))

+ 3 - 2
packages/cpt_main/lib/modules/home/property_news/home_property_news_state.dart

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

+ 44 - 67
packages/cpt_main/lib/modules/home/property_news/home_property_news_view_model.dart

@@ -1,3 +1,6 @@
+import 'package:domain/entity/property_news_entity.dart';
+import 'package:domain/repository/main_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,7 +11,8 @@ import 'home_property_news_state.dart';
 part 'home_property_news_view_model.g.dart';
 
 @riverpod
-class HomePropertyNewsViewModel extends _$HomePropertyNewsViewModel {
+class HomePropertyNewsViewModel extends _$HomePropertyNewsViewModel with DioCancelableMixin{
+  late final MainRepository _mainRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
@@ -20,7 +24,9 @@ class HomePropertyNewsViewModel extends _$HomePropertyNewsViewModel {
 
   @override
   HomePropertyNewsState build() {
-    return HomePropertyNewsState(datas: []);
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = HomePropertyNewsState(datas: []);
+    return state;
   }
 
   //刷新页面状态
@@ -53,44 +59,17 @@ class HomePropertyNewsViewModel extends _$HomePropertyNewsViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
+    // 获取列表
+    var listResult = await _mainRepository.fetchPropertyNewsList(
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
     } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
-
-      state = state.copyWith(datas: allList);
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
@@ -98,33 +77,31 @@ class HomePropertyNewsViewModel extends _$HomePropertyNewsViewModel {
   }
 
 // 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  void handleList(List<PropertyNewsList>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<PropertyNewsList>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
 }

+ 5 - 4
packages/cpt_main/lib/modules/home/property_news/item_list_news.dart

@@ -1,4 +1,5 @@
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/property_news_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
@@ -7,7 +8,7 @@ import 'package:widgets/my_text_view.dart';
 ///  首页新闻News 的Item
 class ListNewsItem extends StatelessWidget {
   final int index;
-  final String item;
+  final PropertyNewsList item;
 
   const ListNewsItem({
     required this.index,
@@ -36,7 +37,7 @@ class ListNewsItem extends StatelessWidget {
         mainAxisSize: MainAxisSize.max,
         children: [
           MyLoadImage(
-            "https://pic.rmb.bdstatic.com/bjh/news/e991d703e32e11c2414ca1298410cc3a8789.jpeg",
+            item.coverImage ?? "",
             width: 100,
             height: 117.5,
           ).marginOnly(right: 18),
@@ -44,7 +45,7 @@ class ListNewsItem extends StatelessWidget {
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               MyTextView(
-                "On Monday, the real estate market stopped falling and stabilized, and a devices",
+                item.title ?? "",
                 marginTop: 12,
                 fontSize: 16,
                 maxLines: 3,
@@ -52,7 +53,7 @@ class ListNewsItem extends StatelessWidget {
                 isFontMedium: true,
               ).expanded(),
               MyTextView(
-                "Monday 14 0ct 2024",
+                item.createdAt ?? "",
                 fontSize: 12,
                 marginBottom: 12,
                 marginTop: 12,

+ 21 - 1
packages/cpt_main/lib/modules/main/main_view_model.dart

@@ -1,6 +1,9 @@
+import 'package:plugin_basic/constants/app_constant.dart';
 import 'package:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'main_state.dart';
 
 part 'main_view_model.g.dart';
@@ -11,7 +14,10 @@ class MainViewModel extends _$MainViewModel with DioCancelableMixin {
   MainState build() {
     final state = MainState();
 
-    registerCancellation();
+    registerEventBus();
+    registerCancellation(callback: () {
+      unregisterEventBus();
+    });
 
     return state;
   }
@@ -21,4 +27,18 @@ class MainViewModel extends _$MainViewModel with DioCancelableMixin {
     UserConfigService.getInstance().refreshUserInfo();
   }
 
+  // EventBus 的事件接收
+  Subscription? subscribe;
+
+  void registerEventBus() {
+    subscribe = bus.on(AppConstant.eventProfileRefresh, (arg) {
+      Log.d("收到消息刷新用户信息");
+      fetchUserInfo();
+    });
+  }
+
+  void unregisterEventBus() {
+    bus.off(AppConstant.eventProfileRefresh, subscribe);
+  }
+
 }

+ 0 - 1
packages/cpt_main/lib/modules/visitor/item_visitor.dart

@@ -38,7 +38,6 @@ class VisitorItem extends StatelessWidget {
           MyTextView(
             item.name ?? "",
             fontSize: 16,
-            marginTop: 19,
             marginBottom: 5,
             textColor: context.appColors.textBlack,
             isFontMedium: true,

+ 6 - 6
packages/cpt_main/lib/modules/visitor/visitor_page.dart

@@ -49,8 +49,8 @@ class VisitorPage extends HookConsumerWidget {
                     _buildVisitorCategory(
                       context,
                       Assets.mainVisitorNow,
-                      54.5,
-                      48,
+                      70,
+                      70,
                       S.current.visitor_now,
                       tabsRouter.activeIndex == 0,
                     ).onTap(
@@ -61,8 +61,8 @@ class VisitorPage extends HookConsumerWidget {
                     _buildVisitorCategory(
                       context,
                       Assets.mainVisitorActive,
-                      36.5,
-                      48,
+                      70,
+                      70,
                       S.current.visitor_active,
                       tabsRouter.activeIndex == 1,
                     ).onTap(
@@ -73,8 +73,8 @@ class VisitorPage extends HookConsumerWidget {
                     _buildVisitorCategory(
                       context,
                       Assets.mainVisitorHistory,
-                      38,
-                      45.5,
+                      70,
+                      70,
                       S.current.history,
                       tabsRouter.activeIndex == 2,
                     ).onTap(

+ 4 - 1
packages/cpt_profile/lib/modules/setting/setting_page.dart

@@ -73,7 +73,10 @@ class SettingPage extends HookConsumerWidget {
             SettingItemContainer(title: S.current.account_deactivation).onTap(viewModel.doDeleteAccount),
 
             //评价我们
-            SettingItemContainer(title: S.current.rate_us),
+            SettingItemContainer(title: S.current.rate_us).onTap((){
+              //跳转到应用商城
+              viewModel.rateUs();
+            }),
 
             //版本号
             SettingItemContainer(

+ 7 - 0
packages/cpt_profile/lib/modules/setting/setting_view_model.dart

@@ -9,6 +9,7 @@ import 'package:plugin_platform/engine/sp/sp_util.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
+import 'package:shared/utils/event_bus.dart';
 import 'package:widgets/dialog/app_default_dialog.dart';
 
 part 'setting_view_model.g.dart';
@@ -62,4 +63,10 @@ class SettingViewModel extends _$SettingViewModel {
       },
     ));
   }
+
+  //评价我们,跳转到各平台的应用商城
+  void rateUs() {
+    bus.emit(AppConstant.eventProfileRefresh, true);
+  }
+
 }

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

@@ -394,28 +394,28 @@ class PropertyIoanPage extends HookConsumerWidget {
               ),
             )
           ),
-          Visibility(
-            visible: state.loadingState == LoadState.State_Success,
-            child: Container(
-              height: 50,
-              color: ColorUtils.string2Color('#4161D0'),
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.center,
-                children: [
-                  // MyLoadImage(Assets.propertyIoanItemBg,width: 60,height: 50,),
-                  const SizedBox(width: 10,),
-                  MyTextView(
-                    "Request a Quote",
-                    fontSize: 16,
-                    textColor: Colors.white,
-                    isFontMedium: true,
-                  ),
-                ],
-              ),
-            ).onTap((){
-              _vm.handlerRequestQuote(context);
-            }),
-          )
+          // Visibility(
+          //   visible: state.loadingState == LoadState.State_Success,
+          //   child: Container(
+          //     height: 50,
+          //     color: ColorUtils.string2Color('#4161D0'),
+          //     child: Row(
+          //       mainAxisAlignment: MainAxisAlignment.center,
+          //       children: [
+          //         // MyLoadImage(Assets.propertyIoanItemBg,width: 60,height: 50,),
+          //         const SizedBox(width: 10,),
+          //         MyTextView(
+          //           "Request a Quote",
+          //           fontSize: 16,
+          //           textColor: Colors.white,
+          //           isFontMedium: true,
+          //         ),
+          //       ],
+          //     ),
+          //   ).onTap((){
+          //     _vm.handlerRequestQuote(context);
+          //   }),
+          // )
         ],
       ),
     );

+ 6 - 6
packages/cpt_property/lib/modules/news/page/property_news_page.dart

@@ -136,7 +136,7 @@ class PropertyNewsPage extends HookConsumerWidget {
           Positioned(
             right: 5,
             bottom: 0,
-            child: MyAssetImage(liked? Assets.propertyCollectionActive:Assets.propertyCollection,width:22,height: 20.5,).onTap((){
+            child: MyAssetImage(liked? Assets.propertyCollectionActive:Assets.propertyCollection,width:22.5,height: 21,).onTap((){
               Log.d("点击了收藏按钮");
               vm.handlerCollection(item, liked);
             }),
@@ -181,10 +181,7 @@ class PropertyNewsPage extends HookConsumerWidget {
           minHeight: 117.5,
         ),
       ],
-    ).onTap((){
-      // 去详情
-      // vm.goNewsDetail(item);
-    });
+    );
   }
 
 
@@ -230,7 +227,10 @@ class PropertyNewsPage extends HookConsumerWidget {
                 SliverList(
                   delegate: SliverChildBuilderDelegate(
                         (context, index){
-                          return _buildNewsItem(context, ref, state.list![index], vm);
+                          return _buildNewsItem(context, ref, state.list![index], vm).onTap((){
+                            Log.d("点击了item");
+                            vm.goNewsDetailPage(context, state.list![index]['id']);
+                          });
                         },
                     childCount: state.list!.length
                   )

+ 21 - 2
packages/cpt_property/lib/modules/news/vm/property_news_vm.dart

@@ -1,11 +1,18 @@
+import 'package:auto_route/src/route/page_route_info.dart';
+import 'package:cpt_property/modules/ioan/property_ioan_page.dart';
 import 'package:cpt_property/respository/property_resposity.dart';
+import 'package:cpt_property/router/page/property_page_router.dart';
 import 'package:domain/entity/property_news_entity.dart';
+import 'package:flutter/cupertino.dart';
 import 'package:plugin_platform/http/http_result.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
+import '../../news_detail/property_news_detail_page.dart';
+import '../../property/page/property_page.dart';
 import '../page/property_news_state.dart';
 
 part 'property_news_vm.g.dart';
@@ -18,6 +25,11 @@ class PropertyNewsVm extends _$PropertyNewsVm {
   int _page = 1;  // 当前页
   int _limit = 10; // 每页数量
   int _count = 0; // 总条数
+
+  Map<String, dynamic> _newsQueryMap = {
+    "isCollection": false,
+  };
+
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
     controlFinishRefresh: true,  //允许刷新
@@ -84,6 +96,7 @@ class PropertyNewsVm extends _$PropertyNewsVm {
   Future retryRequest() async {
     _page = 1;
     _needShowPlaceholder = true;
+
     getListData();
   }
 
@@ -98,6 +111,7 @@ class PropertyNewsVm extends _$PropertyNewsVm {
     try {
       //请求网络
       Map<String, dynamic>  params = {
+        "isCollection": _newsQueryMap['isCollection'],
         "page": _page,
         "limit": _limit,
       };
@@ -201,9 +215,9 @@ class PropertyNewsVm extends _$PropertyNewsVm {
 
 
   // 去新闻详情页
-  void goNewsDetail(String item) {
+  void goNewsDetailPage(BuildContext? context, int id) {
     Log.d("goNewsDetail");
-    // PropertyPage.startInstance(context: context, item: item);
+    PropertyNewsDetailPage.startInstance(context: context, id: id,);
   }
 
   // 收藏/取消收藏
@@ -241,4 +255,9 @@ class PropertyNewsVm extends _$PropertyNewsVm {
     }
   }
 
+
+  changeQueryMap(Map<String, dynamic> queryMap){
+    _newsQueryMap = { ..._newsQueryMap, ...queryMap};
+  }
+
 }

+ 1 - 1
packages/cpt_property/lib/modules/news/vm/property_news_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_news_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertyNewsVmHash() => r'928d4b39cb2b66e861543f2dae06d10f4e755b15';
+String _$propertyNewsVmHash() => r'b1bb0fdae0d2fa1f2080a4adeb1f2d0be04f6281';
 
 /// See also [PropertyNewsVm].
 @ProviderFor(PropertyNewsVm)

+ 115 - 13
packages/cpt_property/lib/modules/news_detail/property_news_detail_page.dart

@@ -1,28 +1,40 @@
 
+import 'package:cpt_property/components/bottomDialog.dart';
 import 'package:cpt_property/modules/news_detail/property_news_detail_vm.dart';
+import 'package:cpt_property/modules/rent/page/property_rent_page.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_basic/widget/webview_page.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/ext_dart.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/size_config.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
 import '../../router/page/property_page_router.dart';
 
-//协议页面,也是详情页面的第一个页面入口,内部可以请求详情数据和选项数据
 @RoutePage()
 class PropertyNewsDetailPage extends HookConsumerWidget {
-  final String type;
+  final int id;
 
-  const PropertyNewsDetailPage({Key? key, @PathParam() required this.type}) : super(key: key);
+  const PropertyNewsDetailPage({Key? key, @PathParam() required this.id}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required String formType}) {
+  static void startInstance({BuildContext? context, required int id}) {
     if (context != null) {
-      context.router.push(const PropertyNewsPageRoute());
+      context.router.push(PropertyNewsDetailPageRoute(id: id));
     } else {
-      appRouter.push(const PropertyNewsPageRoute());
+      appRouter.push(PropertyNewsDetailPageRoute(id: id));
     }
   }
 
@@ -33,17 +45,107 @@ class PropertyNewsDetailPage extends HookConsumerWidget {
     useEffect(() {
       // 组件挂载时执行 - 执行接口请求
       // 组件挂载时执行 - 执行接口请求
-      Future.microtask(() => vm.initPageData());
+      Future.microtask(() => vm.initPageData(id));
       return () {
         // 组件卸载时执行
       };
     }, []);
 
-    return state.detailData != null
-        ? WebViewPage(
-      showAppbar: true,
-      initialUrl: state.detailData?['detail_url'],
-      arguments: {'title': state.detailData?['title']},
-    ): const SizedBox.shrink();
+    // return state.detailData != null
+    //     ? WebViewPage(
+    //   showAppbar: true,
+    //   initialUrl: state.detailData?['detail_url'],
+    //   arguments: {'title': state.detailData?['title']},
+    // ): const SizedBox.shrink();
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(
+        context,
+        "News Detail",
+        backgroundColor: context.appColors.backgroundWhite,
+      ),
+      backgroundColor: context.appColors.whiteBG,
+      body: SizedBox(
+          width: double.infinity,
+          height: double.infinity,
+          child: EasyRefresh(
+            controller: vm.refreshController,
+            // 上拉加载
+            onLoad: null,
+            // 下拉刷新
+            onRefresh: null,
+            child: LoadStateLayout(
+              state: state.loadingState,
+              errorMessage: state.errorMessage,
+              errorRetry: () {
+                vm.retryRequest();
+              },
+              successSliverWidget: [
+                SliverList(
+                  delegate: SliverChildBuilderDelegate(
+                          (context, index){
+                        return state.dataRes !=null? _buildContentBox(context, ref, state.dataRes!): Container();
+                      },
+                      childCount: 1
+                  ),
+                )
+              ],
+            ),
+          ).marginOnly(top: 0, bottom: 5)
+      ),
+    );
+  }
+
+
+  Widget _buildContentBox(BuildContext context, WidgetRef ref, Map<String, dynamic> detailInfo) {
+    final title = detailInfo.getValue('title',  '');
+    final coverImage = detailInfo.getValue('cover_image',  '');
+    final content = detailInfo.getValue('content',  '');
+    final createdAt = detailInfo.getValue('created_at',  '');
+    final likesCount = detailInfo.getValue('likes_count',  '');
+    final liked = detailInfo.getValue('liked',  '');
+    return Padding(
+      padding: const EdgeInsets.only(left: 16, right: 16),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          // 标题
+          MyTextView(
+            title,
+            isFontMedium: true,
+            fontSize: 24,
+            textColor: context.appColors.textBlack,
+            marginTop: 5,
+          ),
+          // 时间
+          MyTextView(
+            createdAt,
+            isFontRegular: true,
+            fontSize: 15,
+            textColor: context.appColors.textBlack,
+            marginTop: 11,
+            marginBottom: 17.5,
+          ),
+          // 图片
+          coverImage.isNotEmpty?
+            MyLoadImage(
+              coverImage,
+              width: SizeConfig().screenWidth,
+              height: 190,
+              fit: BoxFit.cover,
+            ) : SizedBox.shrink(),
+          // 内容
+          // MyTextView(
+          //   content,
+          //   isFontRegular: true,
+          //   fontSize: 15,
+          //   textColor: context.appColors.textBlack,
+          //   marginTop: 24.5,
+          // ),
+
+          Html(data: content),
+        ]
+      ),
+    );
   }
 }

+ 16 - 4
packages/cpt_property/lib/modules/news_detail/property_news_detail_state.dart

@@ -1,19 +1,31 @@
+import 'package:widgets/load_state_layout.dart';
+
 class PropertyNewsDetailState {
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
   final String? title;
-  Map<String, dynamic>? detailData;
+  Map<String, dynamic>? dataRes;
 
   PropertyNewsDetailState({
+    this.loadingState = LoadState.State_Loading,
+    String? errorMessage,
     this.title,
-    this.detailData,
+    this.dataRes,
   });
 
   PropertyNewsDetailState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
     String? title,
-    Map<String, dynamic>? detailData,
+    Map<String, dynamic>? dataRes,
   }) {
     return PropertyNewsDetailState(
+      loadingState: loadingState ?? this.loadingState,
+      errorMessage: errorMessage ?? this.errorMessage,
       title: title ?? this.title,
-      detailData: detailData ?? this.detailData,
+      dataRes: dataRes ?? this.dataRes,
     );
   }
 }

+ 268 - 9
packages/cpt_property/lib/modules/news_detail/property_news_detail_vm.dart

@@ -1,26 +1,41 @@
 
 import 'package:cpt_property/modules/news_detail/property_news_detail_state.dart';
+import 'package:domain/entity/property_news_detail_entity.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:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../respository/property_resposity.dart';
 
 part 'property_news_detail_vm.g.dart';
 
 @riverpod
 class PropertyNewsDetailVm extends _$PropertyNewsDetailVm {
+  late PropertyRespository propertyRespositoryInstance;
+
+  bool _needShowPlaceholder = false; //是否展示LoadingView
+  int _page = 1;  // 当前页
+  int _limit = 10; // 每页数量
+  int _count = 0; // 总条数
+
+  late int _detailId; // 详情id
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
 
   PropertyNewsDetailState initState() {
-    return PropertyNewsDetailState(
-        detailData: {
-          "detail_url": "https://www.baidu.com",
-          "title": "详情"
-        }
-    );
+    return PropertyNewsDetailState();
   }
 
   @override
   PropertyNewsDetailState build(){
     // 引入数据仓库
-    // NewsRepositoryInstance = ref.read(newsRepositoryProvider);
+    propertyRespositoryInstance = ref.read(propertyRespositoryProvider);
     final state = initState();
     Log.d("--------------------------build---------------------");
 
@@ -28,12 +43,256 @@ class PropertyNewsDetailVm extends _$PropertyNewsDetailVm {
   }
 
 
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(
+        loadingState: loadState,
+        errorMessage: errorMsg
+    );
+  }
+
   // 初始化页面数据
-  initPageData() {
+  initPageData(int id) {
+    _detailId = id;
+    onRefresh();
+  }
+
+  // 上拉加载 更多
+  Future loadMore() async {
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= _count){
+    //   return;
+    // }else {
+    //   int page = _page + 1;
+    //   state = state.copyWith(page: page,);
+    //   getListData();
+    // }
+    // 检查 page 是否为 null,并初始化为 1
+    _page++;
+    getDetailData();
+  }
+
+
+  // 下拉刷新
+  Future onRefresh() async {
+    // await Future.delayed(const Duration(seconds: 2));
+    _page = 1;
+    getDetailData();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _page = 1;
+    _needShowPlaceholder = true;
+    getDetailData();
   }
 
-  getDetailData(String id) async {
+  getDetailData() async {
     Log.d("getDetailData");
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
 
+
+    try {
+        Map<String, dynamic> params = {
+          "id": _detailId,
+        };
+        final result = await propertyRespositoryInstance.fetchNewsDetail(params);
+        if (result.isSuccess) {
+          handlerResultData(false, data: result.data as PropertyNewsDetailEntity);
+        } else {
+          String errorMessage = result.errorMsg!;
+          changeLoadingState(LoadState.State_Error, errorMessage);
+          ToastEngine.show(result.errorMsg ?? "Network Load Error");
+        }
+    }catch(e){
+      Log.d("获取详情数据失败  $e");
+    }
+  }
+
+
+  // 获取list 列表数据
+  Future getListData<T>() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    Log.d("加载listData数据---------------start--${_page}---");
+    //   try {
+    //     //请求网络
+    //     Map<String, dynamic>  params = {
+    //       "page": _page,
+    //       "limit": _limit,
+    //     };
+    //     Log.d("请求参数------$params");
+    //     final result = await propertyNewsRepository.fetchPropertyNewsList(params);
+    //     Log.d("请求完成结果------${result.data}");
+    //     //校验成功失败
+    //     if (result.isSuccess) {
+    //       // state = state.copyWith(serverTime: result.data);
+    //       state = state;
+    //   handleList(listResult.data?.rows);
+    //       ToastEngine.show("获取数据成功");
+    //     } else {
+    //   errorMessage = listResult.errorMsg;
+    //   changeLoadingState(LoadState.State_Error);
+    //       ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    //     }
+    //   } catch (e) {
+    //     ToastEngine.show("Error: $e");
+    //   }
+
+    // await Future.delayed(const Duration(milliseconds: 1500));
+    // final List<Map<String, dynamic>> listData = [
+    //   {
+    //     "id": 1,
+    //     "title": "Jul 2024  Blk XX #XX to XX 1,100 - 1,200 sqft",
+    //     "price": "\$4000",
+    //     "unit": "per month",
+    //   },
+    //   {
+    //     "id": 2,
+    //     "title": "Jul 2024  Blk XX #XX to XX 1,100 - 1,200 sqft",
+    //     "price": "\$4000",
+    //     "unit": "per month",
+    //   },
+    // ];
+    //
+    // if (_page == 1) {
+    //   //刷新的方式
+    //   state = state.copyWith(list: listData);
+    //   refreshController.finishRefresh();
+    //   //更新展示的状态
+    //   changeLoadingState(LoadState.State_Success, null);
+    // } else {
+    //   //加载更多
+    //   final allList = state.list;
+    //   if(allList.length >= _count! * _limit!){
+    //     //更新展示的状态
+    //     changeLoadingState(LoadState.State_Success, null);
+    //     refreshController.finishLoad(IndicatorResult.noMore, true);
+    //   }else {
+    //     allList.addAll(listData);
+    //     state = state.copyWith(list: allList);
+    //     refreshController.finishLoad();
+    //   }
+    // }
+    //
+
+    // try {
+    //   //请求网络
+    //   Map<String, dynamic>  params = {
+    //     "type": 2, // 1 sale 2 rent
+    //     "page": _page,
+    //     "limit": _limit,
+    //   };
+    //   Log.d("请求参数------$params");
+    //   final result = await propertyRespositoryInstance.fetchTransactionList(params);
+    //   //校验成功失败
+    //   if (result.isSuccess) {
+    //     // state = state.copyWith(count: (result.data as PropertySaleRentEntity).count);
+    //     handlerResultList((result.data  as PropertySaleRentEntity).list);
+    //   } else {
+    //     String errorMessage = result.errorMsg!;
+    //     changeLoadingState(LoadState.State_Error, errorMessage);
+    //     ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    //   }
+    // } catch (e) {
+    //   ToastEngine.show("Error: $e");
+    // }
+
+    // // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // void handlerResultList(List<PropertySaleRentList>? list) {
+  //   if (list != null && list.isNotEmpty) {
+  //     //有数据,判断是刷新还是加载更多的数据
+  //     if (_page == 1) {
+  //       //刷新的方式
+  //       state.list!.clear();
+  //       state.list!.addAll(list.map((item)=> item.toJson()).toList());
+  //       refreshController.finishRefresh();
+  //
+  //       //更新展示的状态
+  //       changeLoadingState(LoadState.State_Success, null);
+  //     } else {
+  //       //加载更多
+  //       final allList = state.list;
+  //       state = state.copyWith(list: allList);
+  //       refreshController.finishLoad();
+  //       // update();
+  //     }
+  //   } else {
+  //     if (_page == 1) {
+  //       //展示无数据的布局
+  //       state.list!.clear();
+  //       changeLoadingState(LoadState.State_Empty, null);
+  //       refreshController.finishRefresh();
+  //     } else {
+  //       //展示加载完成,没有更多数据了
+  //       if(state.list!.length == 0){
+  //         changeLoadingState(LoadState.State_Empty, null);
+  //         refreshController.finishLoad();
+  //       }else {
+  //         if(_needShowPlaceholder){
+  //           changeLoadingState(LoadState.State_Success, null);
+  //         }
+  //       }
+  //       //更新展示的状态
+  //       refreshController.finishLoad(IndicatorResult.noMore);
+  //     }
+  //   }
+  // }
+
+  handlerResultData(bool isList, {List<Map<String, dynamic>>? list, PropertyNewsDetailEntity? data}){
+    Future.delayed(const Duration(seconds: 1)).then((value) {
+      if(isList){
+        // list 数据模式
+        if(list != null && list.isNotEmpty){
+          if(_page == 1){
+            // state.list.clear();
+            // state.list!.addAll(list);
+            refreshController.finishRefresh();
+            changeLoadingState(LoadState.State_Success, null);
+          }else {
+            // final allList = state.list;
+            // allList!.addAll(list);
+            // state = state.copyWith(list: allList);
+            refreshController.finishLoad();
+          }
+        }else {
+          if(_page == 1){
+            // state.list.clear();
+            changeLoadingState(LoadState.State_Empty, null);
+            refreshController.finishRefresh();
+          }else {
+            refreshController.finishLoad(IndicatorResult.noMore);
+          }
+        }
+      }else {
+        // 单个数据模式
+        if(data!=null){
+          state = state.copyWith(dataRes: data.toJson());
+          if(_page == 1){
+            refreshController.finishRefresh();
+          }else{
+            refreshController.finishLoad();
+          }
+          changeLoadingState(LoadState.State_Success, null);
+        }else {
+          if(_page == 1){
+            refreshController.finishRefresh();
+          }else{
+            refreshController.finishLoad();
+          }
+          changeLoadingState(LoadState.State_Empty, null);
+        }
+      }
+
+      _needShowPlaceholder = false;
+    });
   }
+
 }

+ 1 - 1
packages/cpt_property/lib/modules/news_detail/property_news_detail_vm.g.dart

@@ -7,7 +7,7 @@ part of 'property_news_detail_vm.dart';
 // **************************************************************************
 
 String _$propertyNewsDetailVmHash() =>
-    r'5e8df693146169ab97ebc3952f33cc2118b0f35e';
+    r'3ec3fcf64c80e1e3ca1af977bc595b54b2d72266';
 
 /// See also [PropertyNewsDetailVm].
 @ProviderFor(PropertyNewsDetailVm)

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

@@ -1,6 +1,8 @@
+import 'package:cs_resources/generated/assets.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';
@@ -13,6 +15,7 @@ import 'package:widgets/my_appbar.dart';
 import '../../../router/page/property_page_router.dart';
 import '../vm/property_vm.dart';
 
+final tabsRouterKey = GlobalKey<AutoTabsRouterState>();
 @RoutePage()
 class PropertyPage extends HookConsumerWidget {
   const PropertyPage({Key? key}) : super(key: key);
@@ -92,13 +95,42 @@ class PropertyPage extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final _vm = ref.read(propertyVmProvider.notifier);
+    final state = ref.watch(propertyVmProvider);
+    final isCollection = useState<bool>(false);
+
+    useEffect((){
+      WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
+        if(tabsRouterKey.currentState?.controller != null){
+          tabsRouterKey.currentState?.controller?.addListener((){
+            _vm.tabsRouterChange();
+          });
+        }
+      });
+
+      return (){
+        Log.d("CommunityPage dispose");
+        tabsRouterKey.currentState?.controller?.removeListener(_vm.tabsRouterChange);
+      };
+    },[]);
     return Scaffold(
         appBar: MyAppBar.appBar(
           context,
           "Property",
           backgroundColor: context.appColors.backgroundWhite,
+          actions: [
+             state.currentPageViewIdx == 1? MyAssetImage(
+              isCollection.value? Assets.propertyCollectionActive: Assets.propertyCollection,
+              width: 22.5,
+              height: 21,
+            ).onTap((){
+               isCollection.value = !isCollection.value;
+              _vm.handlerCollectionFilter(context,isCollection.value);
+            }):Container(),
+            const SizedBox(width: 20),
+          ],
         ),
         body: AutoTabsRouter.pageView(
+          key: tabsRouterKey,
           routes: const [
             PropertyIoanPageRoute(),
             PropertyNewsPageRoute(),

+ 51 - 0
packages/cpt_property/lib/modules/property/page/property_page_state.dart

@@ -0,0 +1,51 @@
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../ioan/property_ioan_page.dart';
+import '../../news/page/property_news_page.dart';
+import '../../rent/page/property_rent_page.dart';
+import '../../sale/page/property_sale_page.dart';
+
+class PropertyVmState {
+  List<Map<String, dynamic>>? topSectionsData;
+  int? currentPageViewIdx;
+
+  PropertyVmState({
+    List<Map<String, dynamic>>? topSectionsData,
+    this.currentPageViewIdx = 0,
+  }) : topSectionsData = topSectionsData?? [
+    {
+      "title": "Ioan",
+      "icon": Assets.propertyIoan,
+      "pageStartInstanceFn": PropertyIoanPage.startInstance,
+      "page": const PropertyIoanPage(),
+    },
+    {
+      "title": "News",
+      "icon": Assets.propertyNews,
+      "pageStartInstanceFn": PropertyNewsPage.startInstance,
+      "page": const PropertyNewsPage(),
+    },
+    {
+      "title": "Sale",
+      "icon": Assets.propertySale,
+      "pageStartInstanceFn": PropertySalePage.startInstance,
+      "page": const PropertySalePage(),
+    },
+    {
+      "title": "Rent",
+      "icon": Assets.propertyRent,
+      "pageStartInstanceFn": PropertyRentPage.startInstance,
+      "page": const PropertyRentPage(),
+    },
+  ];
+
+  PropertyVmState copyWith({
+    List<Map<String, dynamic>>? topSectionsData,
+    int? currentPageViewIdx = 0,
+  }) {
+    return PropertyVmState(
+      topSectionsData: topSectionsData ?? this.topSectionsData,
+      currentPageViewIdx: currentPageViewIdx ?? 0,
+    );
+  }
+}

+ 22 - 62
packages/cpt_property/lib/modules/property/vm/property_vm.dart

@@ -1,4 +1,5 @@
 
+import 'package:cpt_property/modules/news/vm/property_news_vm.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
@@ -9,59 +10,19 @@ import '../../ioan/property_ioan_page.dart';
 import '../../news/page/property_news_page.dart';
 import '../../rent/page/property_rent_page.dart';
 import '../../sale/page/property_sale_page.dart';
+import '../page/property_page.dart';
+import '../page/property_page_state.dart';
 
 part 'property_vm.g.dart';
 
-
-class PropertyVmState {
-  List<Map<String, dynamic>>? topSectionsData;
-  int? curIdx;
-
-  PropertyVmState({
-    List<Map<String, dynamic>>? topSectionsData,
-    this.curIdx = 0,
-  }) : topSectionsData = topSectionsData?? [
-    {
-      "title": "Ioan",
-      "icon": Assets.propertyIoan,
-      "pageStartInstanceFn": PropertyIoanPage.startInstance,
-      "page": const PropertyIoanPage(),
-    },
-    {
-      "title": "News",
-      "icon": Assets.propertyNews,
-      "pageStartInstanceFn": PropertyNewsPage.startInstance,
-      "page": const PropertyNewsPage(),
-    },
-    {
-      "title": "Sale",
-      "icon": Assets.propertySale,
-      "pageStartInstanceFn": PropertySalePage.startInstance,
-      "page": const PropertySalePage(),
-    },
-    {
-      "title": "Rent",
-      "icon": Assets.propertyRent,
-      "pageStartInstanceFn": PropertyRentPage.startInstance,
-      "page": const PropertyRentPage(),
-    },
-  ];
-
-  PropertyVmState copyWith({
-    List<Map<String, dynamic>>? topSectionsData,
-    int? curIdx = 0,
-  }) {
-    return PropertyVmState(
-      topSectionsData: topSectionsData ?? this.topSectionsData,
-      curIdx: curIdx ?? 0,
-    );
-  }
-}
-
 @riverpod
 class PropertyVm extends _$PropertyVm {
   get topSectionsData => state.topSectionsData;
 
+  Map<String, dynamic> _newsQueryMap = {
+    "isCollection": false,
+  };
+
   PropertyVmState initState() {
     return PropertyVmState();
   }
@@ -78,22 +39,21 @@ class PropertyVm extends _$PropertyVm {
     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);
-      }
-    }
+  tabsRouterChange(){
+    // 设置当前导航栏的 图标 等状态
+    Log.d("----tabsRouterChange---${tabsRouterKey.currentState?.controller?.activeIndex}-");
+    state = state.copyWith(currentPageViewIdx: tabsRouterKey.currentState?.controller?.activeIndex ?? 0);
+  }
+
+  // 点击了导航的 搜索 进行筛选
+  handlerCollectionFilter(BuildContext? context, bool isCollection ){
+    _newsQueryMap['isCollection'] = isCollection;
+
+    // 重新加载数据
+    final newsPageVm = ref.read(propertyNewsVmProvider.notifier);
+    newsPageVm..changeQueryMap({
+      "isCollection": _newsQueryMap['isCollection'],
+    })..retryRequest();
   }
 
 }

+ 1 - 1
packages/cpt_property/lib/modules/property/vm/property_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertyVmHash() => r'e9f36995f10e7a4a0897046c50ff9ddd047b58d6';
+String _$propertyVmHash() => r'524ee98015f97fe35fc028fb588fa39b64189784';
 
 /// See also [PropertyVm].
 @ProviderFor(PropertyVm)

+ 1 - 1
packages/cpt_property/lib/modules/rent/vm/property_rent_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_rent_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertyRentVmHash() => r'8af3e7aea46b297f066b9e699713ebea5c06c47a';
+String _$propertyRentVmHash() => r'9d6599ade48d330fcbb81cd7695b939bfb557fa6';
 
 /// See also [PropertyRentVm].
 @ProviderFor(PropertyRentVm)

+ 1 - 1
packages/cpt_property/lib/modules/sale/vm/property_sale_vm.g.dart

@@ -6,7 +6,7 @@ part of 'property_sale_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertySaleVmHash() => r'f7493a35f2d0c93caef3b9a4d7678c94fc42cdfa';
+String _$propertySaleVmHash() => r'63a60ed5fe3a3bdc3d8555fe6afc8a61dce5a675';
 
 /// See also [PropertySaleVm].
 @ProviderFor(PropertySaleVm)

+ 42 - 0
packages/cpt_property/lib/respository/property_resposity.dart

@@ -1,4 +1,5 @@
 import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/property_news_detail_entity.dart';
 import 'package:domain/entity/property_news_entity.dart';
 import 'package:domain/entity/property_sale_rent_entity.dart';
 import 'package:domain/entity/server_time.dart';
@@ -71,6 +72,47 @@ class PropertyRespository {
     return result.convert();
   }
 
+  // 获取 news 详情
+  Future<HttpResult<Object>> fetchNewsDetail(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    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 地址
+      '/api/v1/user/property/news/detail', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    Log.d("------请求返回的result--$result--------");
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = PropertyNewsDetailEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<PropertyNewsDetailEntity>(data: data);
+    }else {
+      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+        ToastEngine.show("${result.errorMsg}");
+      }
+    }
+    return result.convert();
+  }
+
 
   // 点赞/取消点赞
   Future<HttpResult<Object>> fetchPropertyNewsLikeClick(

+ 6 - 0
packages/cpt_property/lib/router/component/property_component_service.dart

@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 
+import '../../modules/news_detail/property_news_detail_page.dart';
 import '../../modules/property/page/property_page.dart';
 
 part 'property_component_service.g.dart';
@@ -22,4 +23,9 @@ class PropertyComponentService extends PropertyService {
   void startPropertyPage() {
     PropertyPage.startInstance();
   }
+
+  @override
+  void startPropertyNewsDetailPage(int id) {
+    PropertyNewsDetailPage.startInstance(id: id);
+  }
 }

+ 9 - 9
packages/cpt_property/lib/router/page/property_page_router.gr.dart

@@ -24,13 +24,13 @@ abstract class _$PropertyPageRouter extends RootStackRouter {
     PropertyNewsDetailPageRoute.name: (routeData) {
       final pathParams = routeData.inheritedPathParams;
       final args = routeData.argsAs<PropertyNewsDetailPageRouteArgs>(
-          orElse: () => PropertyNewsDetailPageRouteArgs(
-              type: pathParams.getString('type')));
+          orElse: () =>
+              PropertyNewsDetailPageRouteArgs(id: pathParams.getInt('id')));
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: PropertyNewsDetailPage(
           key: args.key,
-          type: args.type,
+          id: args.id,
         ),
       );
     },
@@ -81,15 +81,15 @@ class PropertyNewsDetailPageRoute
     extends PageRouteInfo<PropertyNewsDetailPageRouteArgs> {
   PropertyNewsDetailPageRoute({
     Key? key,
-    required String type,
+    required int id,
     List<PageRouteInfo>? children,
   }) : super(
           PropertyNewsDetailPageRoute.name,
           args: PropertyNewsDetailPageRouteArgs(
             key: key,
-            type: type,
+            id: id,
           ),
-          rawPathParams: {'type': type},
+          rawPathParams: {'id': id},
           initialChildren: children,
         );
 
@@ -102,16 +102,16 @@ class PropertyNewsDetailPageRoute
 class PropertyNewsDetailPageRouteArgs {
   const PropertyNewsDetailPageRouteArgs({
     this.key,
-    required this.type,
+    required this.id,
   });
 
   final Key? key;
 
-  final String type;
+  final int id;
 
   @override
   String toString() {
-    return 'PropertyNewsDetailPageRouteArgs{key: $key, type: $type}';
+    return 'PropertyNewsDetailPageRouteArgs{key: $key, id: $id}';
   }
 }
 

+ 19 - 0
packages/cpt_services/lib/constants_services.dart

@@ -0,0 +1,19 @@
+class servicesConstants {
+   static Map<String, Map<String, dynamic>> servicesType = {
+     "houseCleaning": {
+       "name": "房屋保洁",
+       "type": "houseCleaning",
+       'code': 0,
+     },
+     "airConditioner": {
+       "name": "空调保洁",
+       "type": "airConditioner",
+       'code': 1,
+     },
+     "repaire": {
+       "name": "维修",
+       "type": "repaire",
+       'code': 2,
+     }
+  };
+}

+ 0 - 123
packages/cpt_services/lib/modules/services/dialog/account_deactivation_dialog.dart

@@ -1,123 +0,0 @@
-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: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 AccountDeactivationDialog extends StatelessWidget {
-  VoidCallback confirmAction;
-
-  AccountDeactivationDialog({
-    required this.confirmAction,
-  });
-  Widget CheckboxList(BuildContext context) {
-    final List<String> items = ['苹果', '香蕉', '橙子'];
-    final List<bool> selections = [false, false, false];
-    return Expanded(child:ListView.builder(
-      itemCount: items.length,
-      itemBuilder: (context, index) {
-        return Container(
-          padding: EdgeInsets.symmetric(vertical: 5.0),
-          child: CheckboxListTile(
-            value: selections[index],
-            onChanged: (bool? val) {
-              print('Option 1 is now ${val ?? false}');
-              selections[index] = val!;
-            },
-            title: Text(items[index]),
-          ),
-        );
-      },
-    )
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      crossAxisAlignment: CrossAxisAlignment.center,
-      mainAxisAlignment: MainAxisAlignment.center,
-      children: [
-        Container(
-          width: double.infinity,
-          height: 55,
-          decoration: BoxDecoration(
-            color: context.appColors.btnBgDefault,
-            borderRadius: const BorderRadius.only(
-              topRight: Radius.circular(15),
-              topLeft: Radius.circular(15),
-            ),
-          ),
-          child: Row(
-            children: [
-              const SizedBox(width: 45),
-              MyTextView(
-                'Choose a Category',
-                fontSize: 18,
-                textAlign: TextAlign.center,
-                isFontMedium: true,
-                textColor: Colors.white,
-              ).expanded(),
-              const MyAssetImage(
-                Assets.baseServiceDialogDeleteIcon,
-                width: 25,
-                height: 25.5,
-              ).onTap(() {
-                onCancel();
-              }, padding: 10)
-            ],
-          ),
-        ),
-        Container(
-          width: double.infinity,
-          padding: const EdgeInsets.only(top: 22),
-          decoration: BoxDecoration(
-            color: context.appColors.whiteSecondBG,
-            borderRadius: const BorderRadius.only(
-              bottomLeft: Radius.circular(15),
-              bottomRight: Radius.circular(15),
-            ),
-          ),
-          child: Column(
-            children: [
-              Container(height:200, child:CheckboxList(context)),
-              Row(
-                children: [
-                  const SizedBox(width: 18),
-                  Expanded(
-                      flex: 1,
-                      child: InkWell(
-                        onTap: () async {
-                          onCancel();
-                          confirmAction();
-                        },
-                        child: MyTextView(
-                          'Ok',
-                          fontSize: 16,
-                          paddingTop: 13,
-                          paddingBottom: 13,
-                          isFontMedium: true,
-                          textAlign: TextAlign.center,
-                          textColor: Colors.white,
-                          backgroundColor: context.appColors.btnBgDefault,
-                          cornerRadius: 7,
-                        ),
-                      )),
-                  const SizedBox(width: 18),
-                ],
-              ).marginOnly(bottom: 30, top: 28),
-            ],
-          ),
-        ),
-      ],
-    ).constrained(width: 340);
-  }
-
-//取消弹框
-  void onCancel() async {
-    SmartDialog.dismiss();
-  }
-}

+ 148 - 0
packages/cpt_services/lib/modules/services/homeService/home_service_page.dart

@@ -0,0 +1,148 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_rent_entity.dart';
+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:plugin_basic/provider/app_config/app_config_service.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/ext_dart.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_button.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 'package:widgets/widget_export.dart';
+
+import '../../../router/page/services_page_router.dart';
+import 'home_service_vm.dart';
+
+@RoutePage()
+class HomeServicePage extends HookConsumerWidget {
+  const HomeServicePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const HomeServicePageRoute());
+    } else {
+      appRouter.push(const HomeServicePageRoute());
+    }
+  }
+
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(homeServiceVmProvider.notifier);
+    final state = ref.watch(homeServiceVmProvider);
+    // final appConfigState = ref.watch(appConfigServiceProvider)
+
+
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => vm.initPageData());
+      return () {
+        // 组件卸载时执行
+        Log.d("garage_homeService_page 组件卸载时执行");
+      };
+    }, []);
+
+    return Scaffold(
+      // appBar: MyAppBar.appBar(
+      //   context,
+      //   "HomeService",
+      //   backgroundColor: context.appColors.whiteBG,
+      // ),
+      backgroundColor: ColorUtils.string2Color("#F2F3F6"),
+      body: SizedBox(
+          width: double.infinity,
+          height: double.infinity,
+          child: EasyRefresh(
+            key: ValueKey('homeService'),
+            controller: vm.refreshController,
+            // 上拉加载
+            onLoad: () async{
+              Log.d("----onLoad");
+              vm.loadMore();
+            },
+            // 下拉刷新
+            onRefresh: () async{
+              Log.d("----onRefresh");
+              vm.onRefresh();
+            },
+            child: LoadStateLayout(
+              state: state.loadingState,
+              errorMessage: state.errorMessage,
+              errorRetry: () {
+                vm.retryRequest();
+              },
+              successSliverWidget:[
+                SliverGrid(
+                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                    crossAxisCount: 2, // 每行显示两个项目
+                    mainAxisSpacing: 15,
+                    crossAxisSpacing: 15,
+                    // childAspectRatio: 166.5/214, // 宽高比
+                    // childAspectRatio:  166.5/214 * ScreenUtil.getAdapterSizeCtx(context, 166.5/214), // 宽高比
+                    childAspectRatio:  166.5/214 * ((166.5/214).ap), // 宽高比
+                  ),
+                  delegate: SliverChildBuilderDelegate(
+                        (context, index) {
+                      return  _buildHomeServiceItem(context, ref, state.list[index], vm).onTap((){
+                        vm.handlerGotoDetail(context: context, id: state.list[index]['id'], type: 'forSale');
+                      });
+                    },
+                    childCount: state.list.length,
+                  ),
+                ),
+              ],
+            ),
+          ).marginOnly(left: 15,right: 15,top: 15,bottom: 15)
+      ),
+    );
+  }
+
+  Widget _buildHomeServiceItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm){
+    return SizedBox(
+      width: double.infinity,
+      child: Container(
+        decoration: BoxDecoration(
+          color: context.appColors.whiteBG,
+          borderRadius: BorderRadius.circular(8),
+          boxShadow: [
+            BoxShadow(
+              color: ColorUtils.string2Color('#E5E5E5'),
+              offset: const Offset(0, 2),
+              blurRadius: 8,
+            ),
+          ],
+        ),
+        child: Column(
+            mainAxisAlignment: MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              // 卡片头部(头像 标题 时间)
+              // Expanded(
+              //   child: GarageCard(
+              //       key: UniqueKey(),
+              //       itemObj: item.cast<String, dynamic>(),
+              //       onClickColleciotn: (dynamic collectionValue) async {
+              //         Log.d("点击了喜欢按钮  --id:${item['id']}- $collectionValue");
+              //         int id = item['id'];
+              //         return await vm.handlerClickCollection(id, collectionValue);
+              //       }
+              //   ),
+              // ),
+            ]
+        ),
+      ),
+    );
+  }
+}

+ 44 - 0
packages/cpt_services/lib/modules/services/homeService/home_service_state.dart

@@ -0,0 +1,44 @@
+import 'package:widgets/load_state_layout.dart';
+
+class HomeServiceState {
+  //页面 LoadView 状态的展示
+  LoadState loadingState;
+  String? errorMessage;
+
+  String? keyword;
+  bool? isLiked;
+  Map<String, dynamic> activeSortMap;
+  List<Map<String, dynamic>> activeCateGoryList;
+  List<Map<String, dynamic>> list;
+
+
+  HomeServiceState({
+    this.loadingState = LoadState.State_Loading,
+    String? errorMessage,
+    this.keyword,
+    this.isLiked,
+    this.activeSortMap = const {},
+    this.activeCateGoryList = const [],
+    required this.list,
+  });
+
+  HomeServiceState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    String? keyword,
+    bool? isLiked,
+    Map<String, dynamic>? activeSortMap,
+    List<Map<String, dynamic>>? activeCateGoryList,
+    List<Map<String, dynamic>>? list,
+  }) {
+    return HomeServiceState(
+      loadingState: loadingState ?? this.loadingState,
+      errorMessage: errorMessage ?? this.errorMessage,
+      keyword: keyword ?? this.keyword,
+      isLiked: isLiked ?? this.isLiked,
+      activeSortMap: activeSortMap ?? this.activeSortMap,
+      activeCateGoryList: activeCateGoryList ?? this.activeCateGoryList,
+      list: list ?? this.list,
+    );
+  }
+}

+ 337 - 0
packages/cpt_services/lib/modules/services/homeService/home_service_vm.dart

@@ -0,0 +1,337 @@
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_rent_entity.dart';
+import 'package:domain/entity/newsfeed_detail_entity.dart';
+import 'package:flutter/cupertino.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 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../../respository/services_respository.dart';
+import '../../../router/page/services_page_router.dart';
+import 'home_service_state.dart';
+
+part 'home_service_vm.g.dart';
+
+@riverpod
+class HomeServiceVm extends _$HomeServiceVm {
+  late ServicesRespository servicesRespositoryInstance;
+  bool _needShowPlaceholder = false; //是否展示LoadingView
+  int _page = 1;  // 当前页
+  int _limit = 10; // 每页数量
+  int _count = 0; // 总条数
+
+  Map<String, dynamic> _queryParams = {
+    'category_id': null,
+    'keyword': null,
+    'is_liked': null,
+  };
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
+
+  HomeServiceState initState() {
+    return HomeServiceState(
+        list: []
+    );
+  }
+
+  @override
+  HomeServiceState build(){
+    // 引入数据仓库
+    // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
+    final state = initState();
+    Log.d("--------------------------build---------------------");
+
+    return state;
+  }
+
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(
+        loadingState: loadState,
+        errorMessage: errorMsg
+    );
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----home_service_vm-----initPageData   ${state.loadingState}");
+    onRefresh();
+  }
+
+  // 上拉加载 更多
+  Future loadMore() async {
+    Log.d("----home_service_vm-----loadMore");
+    _page++;
+    getListData();
+  }
+
+
+  // 下拉刷新
+  Future onRefresh() async {
+    // 当前pageView 页面正处于显示状态
+    Log.d("----forsale_vm-----onRefresh ");
+    // await Future.delayed(const Duration(seconds: 2));
+    _page = 1;
+    getListData();
+  }
+
+
+  // 手动进行刷新
+  Future triggerRefresh() async {
+    Log.d("trggerRefresh");
+    refreshController.callRefresh();
+  }
+
+  // 手动进行刷新
+  Future directRefresh() async {
+    state = state.copyWith(list:[]);
+    // 注意:由于 nestedscrollview 嵌套easyfresh 组件  refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口
+    // https://github.com/xuelongqy/flutter_easy_refresh/issues/692
+    refreshController.callRefresh();
+    refreshController.resetFooter();
+    _page = 1;
+    _needShowPlaceholder = true;
+    getListData();
+  }
+
+
+  // 重试请求
+  Future retryRequest() async {
+    _page = 1;
+    _needShowPlaceholder = true;
+    getListData();
+  }
+
+
+  // 获取list 列表数据
+  Future getListData<T>({bool? isLoadMore}) async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    List<Map<String, dynamic>> list = [
+      {
+        'id':1,
+        'service_type': 0,  // 0 房屋保洁 1 空调保洁  2 维修
+        'goods_img':  'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500',
+        'resources': ['https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500'],
+        'title': 'House Cleaning Services',
+        'price': '\$66',
+        'isCollection': true,
+        'collection_num': '12',
+        'publisher': 'William Jefferson',
+        'publish_time': 'June 17,2016 at 7:23 p.m.',
+        'publisher_avator': Assets.communityCamera
+      },
+      {
+        'id':1,
+        'service_type': 1,  // 0 房屋保洁 1 空调保洁  2 维修
+        'goods_img':  'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500',
+        'title': 'Electronic keyboard',
+        'price': '\$66',
+        'isCollection': true,
+        'collection_num': '12',
+        'publisher': 'William Jefferson',
+        'publish_time': 'June 17,2016 at 7:23 p.m.',
+        'publisher_avator': Assets.communityCamera
+      },
+      {
+        'id':1,
+        'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
+        'goods_img':  'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500',
+        'title': 'Electronic keyboard',
+        'price': '\$66',
+        'isCollection': true,
+        'collection_num': '12',
+        'publisher': 'William Jefferson',
+        'publish_time': 'June 17,2016 at 7:23 p.m.',
+        'publisher_avator': Assets.communityCamera
+      },
+    ];
+    handlerResultData(true, list:list);
+
+    // try {
+    //   //请求网络
+    //   Map<String, dynamic>  params = {
+    //     "type": 1,  // 类型(1=Sale,2=Rent)
+    //     "category_id": _queryParams['category_id'],
+    //     "keyword": _queryParams['keyword'],
+    //     "page": _page,
+    //     "limit": _limit,
+    //   };
+    //   Log.d("请求参数------$params");
+    //   final result = await servicesRespositoryInstance.fetchGarageDataList(params);
+    //   //校验成功失败
+    //   if (result.isSuccess) {
+    //     // handlerResultList((result.data as GarageSaleRentEntity).list as List<GarageSaleRentList>, isLoadMore ?? false);
+    //   } else {
+    //     String errorMessage = result.errorMsg!;
+    //     changeLoadingState(LoadState.State_Error, errorMessage);
+    //     ToastEngine.show(result.errorMsg ?? "Network Load Error");
+    //   }
+    // } catch (e) {
+    //   ToastEngine.show("Error: $e");
+    // }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+
+  }
+
+  handlerResultData(bool isList, {List<Map<String, dynamic>>? list, dynamic? data}){
+    Future.delayed(const Duration(seconds: 1)).then((value) {
+      if(isList){
+        // list 数据模式
+        if(list != null && list.isNotEmpty){
+          if(_page == 1){
+            state.list.clear();
+            state.list!.addAll(list);
+            refreshController.finishRefresh();
+            changeLoadingState(LoadState.State_Success, null);
+          }else {
+            final allList = state.list;
+            allList!.addAll(list);
+            state = state.copyWith(list: allList);
+            refreshController.finishLoad();
+          }
+        }else {
+          if(_page == 1){
+            state.list.clear();
+            changeLoadingState(LoadState.State_Empty, null);
+            refreshController.finishRefresh();
+          }else {
+            refreshController.finishLoad(IndicatorResult.noMore);
+          }
+        }
+      }else {
+        // 单个数据模式
+        if(data!=null){
+          if(_page == 1){
+            refreshController.finishRefresh();
+          }else{
+            refreshController.finishLoad();
+          }
+          changeLoadingState(LoadState.State_Success, null);
+        }else {
+          if(_page == 1){
+            refreshController.finishRefresh();
+          }else{
+            refreshController.finishLoad();
+          }
+          changeLoadingState(LoadState.State_Empty, null);
+        }
+      }
+    });
+  }
+
+  void handlerResultList(List<GarageSaleRentList>? list, bool isLoadMore) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_page == 1) {
+        //刷新的方式
+        state.list!.clear();
+        state.list!.addAll(list.map((item) => item.toJson()).toList());
+        refreshController.finishRefresh();
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        final allList = state.list;
+        allList!.addAll(list.map((item) => item.toJson()).toList());
+        state = state.copyWith(list: allList);
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_page == 1) {
+        //展示无数据的布局
+        state.list!.clear();
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        if (_page == 1) {
+          //展示无数据的布局
+          state.list!.clear();
+          changeLoadingState(LoadState.State_Empty, null);
+          refreshController.finishRefresh();
+        } else {
+          //展示加载完成,没有更多数据了
+          if(state.list!.length == 0){
+            changeLoadingState(LoadState.State_Empty, null);
+            refreshController.finishLoad();
+          }else {
+            if(_needShowPlaceholder){
+              changeLoadingState(LoadState.State_Success, null);
+            }
+          }
+          //更新展示的状态
+          refreshController.finishLoad(IndicatorResult.noMore);
+        }
+      }
+    }
+  }
+
+
+  // 点击 收藏/取消收藏
+  Future<bool?> handlerClickCollection(int id, bool? isCollection) async{
+    try {
+      //请求网络
+      Map<String, dynamic>  params = {
+        "id": id,
+      };
+      Log.d("请求参数------$params");
+      final result = await servicesRespositoryInstance.fetchGarageColleciton(params);
+      //校验成功失败
+      if (result.isSuccess) {
+        // 修改 该id 的 liked 和 likes_count 字段
+        state.list!.forEach((Map<String, dynamic> element) {
+          GarageSaleRentList elementEntity = GarageSaleRentList.fromJson(element);
+
+          if(elementEntity.id == id){
+            elementEntity.liked = !elementEntity.liked!;
+            elementEntity.likesCount = elementEntity.liked! ? (elementEntity.likesCount! + 1) : (elementEntity.likesCount! - 1);
+          }
+
+          element = elementEntity.toJson();
+
+        });
+        return true;
+      } else {
+        String errorMessage = result.errorMsg!;
+        changeLoadingState(LoadState.State_Error, errorMessage);
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      Log.e("Error: $e");
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 设置当前的 _queryParams
+  setCurrentQueryParams(Map<String, dynamic> params){
+    _queryParams.addAll(params);
+  }
+
+  // 获取当前的 _queryParams
+  Map<String, dynamic> getCurrentQueryParams(String? key){
+    if(key!=null && key!.isNotEmpty){
+      return _queryParams[key];
+    }
+    return _queryParams;
+  }
+
+  // 去详情页面
+  void handlerGotoDetail({BuildContext? context, required int id, String type='forSale'}){
+    Log.d("去详情页面");
+    // appRouter.push(GaragesaleDetailPageRoute(id: id, type: 'forSale'));
+  }
+}

+ 10 - 10
packages/cpt_services/lib/modules/services_detail/services_detail_vm.g.dart

@@ -1,26 +1,26 @@
 // GENERATED CODE - DO NOT MODIFY BY HAND
 
-part of 'services_detail_vm.dart';
+part of 'home_service_vm.dart';
 
 // **************************************************************************
 // RiverpodGenerator
 // **************************************************************************
 
-String _$servicesDetailVmHash() => r'7fe0ebbd7df15c661751f2b01a9d2efe53f975c7';
+String _$homeServiceVmHash() => r'b0e883932798f7e0dfd413dd1cdadf758cd13173';
 
-/// See also [ServicesDetailVm].
-@ProviderFor(ServicesDetailVm)
-final servicesDetailVmProvider =
-    AutoDisposeNotifierProvider<ServicesDetailVm, ServicesDetailState>.internal(
-  ServicesDetailVm.new,
-  name: r'servicesDetailVmProvider',
+/// See also [HomeServiceVm].
+@ProviderFor(HomeServiceVm)
+final homeServiceVmProvider =
+    AutoDisposeNotifierProvider<HomeServiceVm, HomeServiceState>.internal(
+  HomeServiceVm.new,
+  name: r'homeServiceVmProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
       ? null
-      : _$servicesDetailVmHash,
+      : _$homeServiceVmHash,
   dependencies: null,
   allTransitiveDependencies: null,
 );
 
-typedef _$ServicesDetailVm = AutoDisposeNotifier<ServicesDetailState>;
+typedef _$HomeServiceVm = AutoDisposeNotifier<HomeServiceState>;
 // 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

+ 231 - 0
packages/cpt_services/lib/modules/services/homeService/service_card_item.dart

@@ -0,0 +1,231 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/ext_dart.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 '../../../constants_services.dart';
+
+
+// 'id':1,
+// 'goods_img':  'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500',
+// 'title': 'Electronic keyboard',
+// 'price': '\$66',
+// 'isCollection': true,
+// 'collection_num': '12',
+// 'publisher': 'William Jefferson',
+// 'publish_time': 'June 17,2016 at 7:23 p.m.',
+// 'publisher_avator': Assets.communityCamera,'
+
+
+class HomeServiceCard extends StatelessWidget {
+  Map<String, dynamic>? serviceType = servicesConstants.servicesType['houseCleaning'];
+  Map<String, dynamic> itemObj;
+  double? cardHeight;
+  final Function()? onTap;
+  final Function(dynamic)? onClickColleciotn;
+
+  HomeServiceCard({
+    Key? key,
+    this.serviceType,
+    required this.itemObj,
+    this.onTap,
+    this.onClickColleciotn,
+    double? cardHeight,
+  }) : super(key: key) {
+    this.cardHeight ??= 214;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    List? card_resources = itemObj.getValue<List>("resources", [])?? [];
+    String card_img = card_resources.length>0? card_resources[0]:"";
+    String card_title = itemObj.getValue("title", "");
+    int card_price = itemObj.getValue("price", "");
+    String card_created_at = itemObj.getValue("created_at", "");
+    Map<String, dynamic>? card_account = itemObj.getValue<Map<String,dynamic>>("account", null);
+    String card_avatar = card_account?['avatar']?? "";
+    String card_publish_name = card_account?['name']?? "";
+    bool card_liked = itemObj.getValue("liked", false);
+    int card_likes_count = itemObj.getValue("likes_count", 0);
+    return Column(
+      children: [
+        // 图片
+        Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            Expanded(
+              child: ClipRRect(
+                borderRadius: const BorderRadius.only(topLeft: Radius.circular(8), topRight: Radius.circular(8),),
+                child: MyLoadImage(
+                  card_img,
+                  width: 166.5,
+                  height: 102.5.ap,
+                  isCircle: false,
+                  fit: BoxFit.cover,
+                ),
+              ),
+            ),
+          ],
+        ),
+        // 标题
+        Padding(
+          padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
+          child: Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              Expanded(
+                child: MyTextView(
+                  card_title,
+                  maxLines: 1,
+                  isTextEllipsis: true,
+                  textAlign: TextAlign.left,
+                  textColor: context.appColors.textBlack,
+                  fontSize: 16,
+                  isFontRegular: true,
+                ),
+              ),
+            ],
+          ),
+        ),
+        // 价格 及 收藏
+        Padding(
+          padding: const EdgeInsets.only(left: 10, right: 10,top: 0, bottom: 0),
+          child: Row(
+            mainAxisAlignment: MainAxisAlignment.spaceAround,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              Expanded(
+                child: MyTextView(
+                  '$card_price',
+                  maxLines: 1,
+                  isTextEllipsis: true,
+                  textAlign: TextAlign.start,
+                  textColor: ColorUtils.string2Color('#4161D0'),
+                  fontSize: 18,
+                  isFontMedium: true,
+                ),
+              ),
+              // 动态的 收藏数
+              CollectionWidget(
+                collectionNum: card_likes_count,
+                isCollection: card_liked,
+                onClickColleciotn: onClickColleciotn,
+              ),
+            ],
+          ),
+        ),
+        // 发布人信息
+        Expanded(
+          child: Padding(
+              padding: EdgeInsets.only(left: 10, right: 10, bottom: 17.5),
+              child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceAround,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    Expanded(
+                        child: Column(
+                            mainAxisAlignment: MainAxisAlignment.center,
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            mainAxisSize: MainAxisSize.max,
+                            children: [
+                              MyTextView(
+                                card_publish_name,
+                                maxLines: 1,
+                                isTextEllipsis: true,
+                                textAlign: TextAlign.start,
+                                marginLeft: 13,
+                                fontSize: 12,
+                                textColor: ColorUtils.string2Color('#2956B7'),
+                                isFontRegular: true,
+                              ),
+                              MyTextView(
+                                card_created_at,
+                                maxLines: 1,
+                                isTextEllipsis: true,
+                                textAlign: TextAlign.start,
+                                marginLeft: 13,
+                                marginTop: 5,
+                                fontSize: 10,
+                                textColor: context.appColors.textBlack,
+                                isFontRegular: true,
+                              ),
+                            ]
+                        )
+                    ),
+                  ]
+              )
+          ),
+        )
+      ],
+    );
+  }
+}
+
+
+
+class CollectionWidget extends HookConsumerWidget {
+  int collectionNum = 0;
+  bool isCollection = false;
+  final Function(dynamic)? onClickColleciotn;
+  CollectionWidget({
+    Key? key,
+    required this.collectionNum,
+    required this.isCollection,
+    this.onClickColleciotn,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final collectionNumState = useState(collectionNum);
+    final isCollectionState = useState(isCollection);
+    return Container(
+        width: 60,
+        height: 30,
+        alignment: Alignment.center,
+        // decoration: BoxDecoration(
+        //   color: ColorUtils.string2Color('#E5E5E5'),
+        //   borderRadius: BorderRadius.circular(15),
+        // ),
+        child: Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              MyTextView(
+                '${collectionNumState.value}',
+                textColor: context.appColors.textBlack,
+                fontSize: 14,
+                isFontRegular: true,
+                marginRight: 7,
+              ),
+              MyLoadImage(
+                isCollectionState.value? Assets.communityLikeActive: Assets.communityLike,
+                width: 14.1,
+                height: 14,
+              )
+            ]
+          // 点击 收餐/取消收藏
+        ).onTap(() async{
+          // Log.d("点击了收藏按钮  ${isCollectionState.value}");
+          // ToastEngine.show("点击了收藏按钮 ${isCollectionState.value}");
+          final result = await onClickColleciotn?.call(isCollectionState.value);
+          if(result !=null && result){
+            isCollectionState.value = !isCollectionState.value;
+            collectionNumState.value = (collectionNumState.value + (isCollectionState.value? 1: -1))<0? 0: (collectionNumState.value + (isCollectionState.value? 1: -1));
+            if(isCollectionState.value){
+              // ToastEngine.show("Collect Success");
+            }else {
+              // ToastEngine.show("Cancel Collect Success");
+            }
+          }
+        })
+    );
+  }
+}

+ 320 - 214
packages/cpt_services/lib/modules/services/services_page.dart

@@ -1,214 +1,320 @@
-import 'package:cpt_services/modules/services_list/services_list_page.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:cs_resources/generated/assets.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:widgets/ext/ex_widget.dart';
-import 'package:widgets/load_state_layout.dart';
-import 'package:widgets/my_appbar.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/widget_export.dart';
-
-import '../../../router/page/services_page_router.dart';
-import 'services_view_model.dart';
-
-@RoutePage()
-class ServicesPage extends HookConsumerWidget {
-  const ServicesPage({Key? key}) : super(key: key);
-
-  //启动当前页面
-  static void startInstance({BuildContext? context}) {
-    if (context != null) {
-      context.router.push(const ServicesPageRoute());
-    } else {
-      appRouter.push(const ServicesPageRoute());
-    }
-  }
-
-  Widget _buildTop(BuildContext context, WidgetRef ref, _vm) {
-    // List itemsList = _vm.state.list.toList();
-    return Container(
-        color: ColorUtils.string2Color('#FFFFFF'),
-        child: Column(children: [
-          Container(
-            width: double.infinity,
-            height: 160,
-            decoration: const BoxDecoration(
-              image: DecorationImage(
-                image: AssetImage(
-                    'packages/cs_resources/${Assets.propertyHomeLoanBg}'),
-                fit: BoxFit.fill, // 设置图片平铺
-              ),
-            ),
-          ).marginOnly(bottom: 15),
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              const Text(
-                'Home Services!',
-                style: TextStyle(
-                    fontSize: 16.0,
-                    color: Colors.black,
-                    fontWeight: FontWeight.w400), // 设置字体大小
-              ),
-              TextButton(
-                onPressed: () {
-                  _vm.doDeleteAccount();
-                },
-                style: TextButton.styleFrom(
-                  foregroundColor: Colors.black,
-                  backgroundColor: ColorUtils.string2Color('#4161D0'), // 背景颜色
-                  minimumSize: const Size(70, 30), // 最小宽度和高度
-                  padding: const EdgeInsets.symmetric(
-                      horizontal: 11.0, vertical: 9), // 内边距
-                  shape: RoundedRectangleBorder(
-                    borderRadius: BorderRadius.circular(5), // 圆角
-                    side: BorderSide(
-                      color: ColorUtils.string2Color('#4161D0'),
-                      width: 1.0,
-                    ), // 边框
-                  ),
-                ),
-                child: const Text(
-                  'Filter',
-                  style: const TextStyle(
-                    color: Colors.white,
-                  ),
-                ),
-              ),
-            ],
-          ),
-        ])).paddingOnly(top: 10, left: 15, right: 15);
-  }
-
-  Widget _buildItem(BuildContext context, WidgetRef ref, _vm, item) {
-    return Container(
-            width: MediaQuery.of(context).size.width / 2 - 25,
-            height: 146,
-            decoration: const BoxDecoration(
-              color: Colors.white,
-              borderRadius: BorderRadius.all(Radius.circular(6.0)),
-              boxShadow: [
-                BoxShadow(
-                    color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
-              ],
-            ),
-            child: Column(
-              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-              children: [
-                Row(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Expanded(
-                      child: Text(
-                        maxLines: 2, // 设置最大行数为2
-                        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
-                        item['title'],
-                        style: const TextStyle(
-                            fontSize: 16.0,
-                            color: Colors.black,
-                            fontWeight: FontWeight.w700),
-                      ),
-                    )
-                  ],
-                ),
-                Row(
-                  mainAxisAlignment: MainAxisAlignment.end,
-                  children: [
-                    MyAssetImage(
-                      item['price'],
-                      width: 110,
-                      height: 80,
-                    )
-                  ],
-                ),
-              ],
-            ).paddingOnly(top: 15, left: 15).onTap(() {
-          // 去详情
-          // _vm.goNewsDetail(item['title']);
-          Navigator.push(
-            context,
-            MaterialPageRoute(builder: (context) => const ServicesListPage()),
-          );
-        }))
-        .marginOnly(bottom: 15);
-  }
-
-// list
-  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
-    List itemsList = _vm.state.list.toList();
-    return ListView.builder(
-      itemCount: itemsList.length,
-      itemBuilder: (context, index) {
-        bool noLast = !(index == itemsList.length - 1);
-        bool isLast = index == itemsList.length - 1;
-        if (index % 2 == 0 && noLast) {
-          return Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              _buildItem(context, ref, _vm, itemsList[index]),
-              _buildItem(context, ref, _vm, itemsList[index + 1]),
-            ],
-          );
-        } else if (index % 2 != 0 && noLast) {
-          return Row();
-        } else if (index % 2 != 0 && isLast) {
-          return Row();
-        } else {
-          return Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              _buildItem(context, ref, _vm, itemsList[index]),
-            ],
-          );
-        }
-        // _buildSaleItem(context, ref, itemsList[index], _vm);
-      },
-    );
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final state = ref.watch(servicesVmProvider);
-    final _vm = ref.read(servicesVmProvider.notifier);
-    return Scaffold(
-      appBar: MyAppBar.appBar(
-        context,
-        "Service",
-        backgroundColor: context.appColors.backgroundWhite,
-      ),
-      body: Container(
-        child: Column(
-          children: [
-            _buildTop(context, ref, _vm),
-            Expanded(
-              child: EasyRefresh(
-                // 上拉加载
-                onLoad: () async {
-                  Log.d("----onLoad");
-                  _vm.onLoadData();
-                },
-                // 下拉刷新
-                onRefresh: () async {
-                  Log.d("----onRefresh");
-                  _vm.refreshListData();
-                },
-                child: Container(
-                    color: ColorUtils.string2Color('#F2F3F6'),
-                    padding: const EdgeInsets.only(
-                        bottom: 15, left: 15, right: 15, top: 15),
-                    child: _buildSaleList(context, ref, _vm)),
-              ),
-            )
-          ],
-        ),
-      ),
-    );
-  }
-}
+
+import 'package:cpt_services/modules/services/services_pageview_idx_data.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:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package: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 'package:widgets/widget_export.dart';
+
+import '../../router/page/services_page_router.dart';
+import 'services_vm.dart';
+
+final tabsRouterKey = GlobalKey<AutoTabsRouterState>();
+final GlobalKey<ExtendedNestedScrollViewState> extendedNestedScrollViewKey =
+GlobalKey<ExtendedNestedScrollViewState>();
+@RoutePage()
+class ServicesPage extends HookConsumerWidget with WidgetsBindingObserver {
+  ServicesPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push( ServicesPageRoute());
+    } else {
+      appRouter.push( ServicesPageRoute());
+    }
+  }
+
+  bool _isKeyboardVisible = false;
+
+  void handlerNestedScrollViewScroll({double? outerOffset, double? innerOffset, bool? isOuterScrollAnimated=false, bool? isInnerScrollAnimated=false}){
+
+    if(outerOffset !=null){
+      if(isOuterScrollAnimated!){
+        extendedNestedScrollViewKey.currentState?.outerController.animateTo(
+          outerOffset,
+          duration: const Duration(seconds: 1),
+          curve: Curves.easeIn,
+        );
+      }else {
+        extendedNestedScrollViewKey.currentState?.outerController.jumpTo(
+          outerOffset,
+        );
+      }
+    }
+
+    if(innerOffset !=null){
+      extendedNestedScrollViewKey.currentState?.innerPositions.forEach((position) {
+        if(isInnerScrollAnimated!){
+          position.animateTo(innerOffset,
+              duration: Duration(seconds: 1), curve: Curves.easeIn);
+        }else {
+          position.jumpTo(innerOffset);
+        }
+      });
+    }
+  }
+
+  @override
+  void didChangeMetrics() {
+    final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom;
+    final newValue = bottomInset > 0.0;
+    if (_isKeyboardVisible != newValue) {
+      _isKeyboardVisible = newValue;
+      if (_isKeyboardVisible) {
+        handlerNestedScrollViewScroll(innerOffset: 0.0,);
+        print("键盘已显示");
+      } else {
+        WidgetsBinding.instance.removeObserver(this);
+        print("键盘已隐藏");
+      }
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final vm = ref.read(servicesVmProvider.notifier);
+    final state = ref.watch(servicesVmProvider);
+
+    useEffect(() {
+      // 监听窗口
+      WidgetsBinding.instance.addObserver(this);
+    }, []);
+
+
+
+    useEffect((){
+      Log.d("ServicesPage initState");
+      // 延迟监听
+      WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
+        if(tabsRouterKey.currentState?.controller != null){
+          tabsRouterKey.currentState?.controller?.addListener((){
+            vm.tabsRouterChange();
+          });
+        }
+      });
+
+      return (){
+        Log.d("ServicesPage dispose");
+        WidgetsBinding.instance.removeObserver(this);
+        tabsRouterKey.currentState?.controller?.removeListener(vm.tabsRouterChange);
+      };
+    },[]);
+
+    return Scaffold(
+        appBar: MyAppBar.searchAppBar(
+            context,
+            value: vm.getCurrentQueryParams('keyword'),
+            actions: [
+              const MyAssetImage(
+                Assets.serviceServiceIcon1,
+                width: 21.5,
+                height: 21.5,
+              ).onTap((){
+                vm.handlerClickNavbarLikeBtn(context);
+              }),
+              const SizedBox(width: 15),
+            ],
+            backgroundColor: context.appColors.backgroundWhite,
+            onSearch: (value) {
+              vm.handlerSearch(value);
+            }
+        ),
+        backgroundColor: context.appColors.backgroundDefault,
+        body:  ExtendedNestedScrollView(
+            key: extendedNestedScrollViewKey,
+            onlyOneScrollInBody: true,
+            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
+              return [
+                // SliverPersistentHeader(
+                //   delegate: CustomSliverPersistentHeaderDelegate(
+                //     maxHeight: 180,
+                //     minHeight: 180,
+                //     child: _buildTopSection(context, ref, vm, state),
+                //   ),
+                //   pinned: false,
+                // ),
+                // top 组件,转换为 Sliver 组件
+                SliverToBoxAdapter(
+                  child: _buildTopSection(context, ref, vm, state),
+                ),
+              ];
+            },
+            body: Column(
+                mainAxisSize: MainAxisSize.max,
+                children: [
+                  Expanded(
+                      child: AutoTabsRouter.pageView(
+                        key: tabsRouterKey,
+                        routes: const [
+                          HomeServicePageRoute(),
+                        ],
+                        builder: (context, child, pageController) {
+                          final tabsRouter = AutoTabsRouter.of(context);
+                          return Column(
+                            children: [
+                              Expanded(
+                                  child: child
+                              ),
+                            ],
+                          );
+                        },
+                      )
+                  )
+                ]
+            )
+        )
+    );
+  }
+
+
+  Widget _buildTopSection(BuildContext context, WidgetRef ref, vm, state) {
+    final topSectionsData = vm.topSectionsData;
+    final currentPageIdx = tabsRouterKey.currentState?.controller?.activeIndex ?? 0;
+    return Container(
+      color: context.appColors.whiteBG,
+      padding: const EdgeInsets.only(top: 23, bottom: 30),
+      child: Center(
+        child: Row(
+          mainAxisSize: MainAxisSize.max,
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: List.generate(topSectionsData.length, (index) {
+            final item = topSectionsData[index];
+            return Column(
+              children: [
+                Container(
+                  width: MediaQuery.of(context).size.width / topSectionsData.length - 36,
+                  height: 70,
+                  decoration: BoxDecoration(
+                    shape: BoxShape.circle, // 设置为圆形
+                    color: ColorUtils.string2Color("#F0F8FF"),
+                    boxShadow: index == currentPageIdx ? [
+                      BoxShadow(
+                        color: context.appColors.tabLightBlueShadow, // 设置阴影颜色
+                        blurRadius: 5, // 设置模糊半径
+                        spreadRadius: 0.05, // 控制阴影扩散
+                        offset: const Offset(0, 4), // 设置阴影偏移量
+                      ),] : [],// 未选中时无阴影,
+                  ),
+                  child: MyAssetImage(
+                    item['icon'],
+                    width: MediaQuery.of(context).size.width / topSectionsData.length - 36,
+                    // width: 70,
+                    height: 70,
+                  ).onTap(() {
+                  },
+                    type: ClickType.throttle,
+                  ),
+                ),
+                SizedBox.fromSize(size: const Size(0, 9)),
+                MyTextView(
+                  item['title'],
+                  fontSize: 15,
+                  textColor: index == currentPageIdx ? ColorUtils.string2Color('#4161D0'): context.appColors.textBlack,
+                  textAlign: TextAlign.center,
+                  isFontMedium: true,
+                ),
+              ],
+            ).marginOnly(left: 18, right: 18, top: 10, bottom: 10);
+          }),
+        ),
+      ),
+    );
+  }
+
+  Widget _buildNewsFeedPost(BuildContext context, WidgetRef ref, vm, state){
+    final userConfig = UserConfigService.getState(ref: ref);
+    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.servicesNewsFeed, width: 45,height: 45,),
+          MyLoadImage(
+            userConfig.user?.avatar,
+            width: 45,
+            height: 45,
+            isCircle: true,
+            fit: BoxFit.fill,
+          ),
+          Expanded(
+            child: MyTextView(
+              "What’s on your mind?",
+              textColor: context.appColors.textBlack,
+              fontSize: 15,
+              marginLeft: 15,
+              alignment: Alignment.centerLeft,
+              textAlign: TextAlign.left,
+              backgroundColor: ColorUtils.string2Color('#ffffff'),
+              maxLines: 1,
+              isFontMedium: true,
+            ),
+          ),
+          const MyAssetImage(
+            Assets.serviceServiceIcon1,
+            width: 21,
+            height: 16.5,
+          ),
+        ],
+      ).onTap((){
+        vm.handlerGotoNewsfeedPost(context);
+      }),
+    );
+  }
+
+  Widget _buildGarageSalePost(BuildContext context, WidgetRef ref, vm, state){
+    final userConfig = UserConfigService.getState(ref: ref);
+    return Container(
+      height: 65.5,
+      width: double.infinity,
+      padding: const EdgeInsets.only(left: 20, right: 20),
+      color: Colors.white,
+      child: Row(
+        children: [
+          MyLoadImage(
+            userConfig.user?.avatar,
+            width: 45,
+            height: 45,
+            isCircle: true,
+            fit: BoxFit.fill,
+          ),
+          Expanded(
+            child: MyTextView(
+              "Sell Item",
+              textColor: context.appColors.textBlack,
+              fontSize: 15,
+              marginLeft: 15,
+              alignment: Alignment.centerLeft,
+              textAlign: TextAlign.left,
+              backgroundColor: ColorUtils.string2Color('#ffffff'),
+              maxLines: 1,
+              isFontMedium: true,
+            ),
+          ),
+          const MyAssetImage(
+            Assets.serviceServiceIcon1,
+            width: 21,
+            height: 16.5,
+          ),
+        ],
+      ).onTap((){
+        vm.handlerGotoGaragePost(context);
+      }),
+    );
+  }
+}
+

+ 13 - 0
packages/cpt_services/lib/modules/services/services_pageview_idx_data.dart

@@ -0,0 +1,13 @@
+
+class ServicesPageviewIdxData {
+  static const int homeService = 0;
+  static const int inProgress = 1;
+  static const int history = 2;
+
+
+  static Map<int, String> get values => {
+    0: "homeService",
+    1: "inProgress",
+    2: "history",
+  };
+}

+ 0 - 70
packages/cpt_services/lib/modules/services/services_repository.dart

@@ -1,70 +0,0 @@
-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 'services_state.dart';
-part 'services_repository.g.dart';
-
-@Riverpod(keepAlive: true)
-ServicesRepository servicesRepository(Ref ref) {
-  final dioEngine = ref.watch(dioEngineProvider);
-  return ServicesRepository(dioEngine: dioEngine);
-}
-
-/*
- * 数据仓库
- */
-class ServicesRepository {
-  DioEngine dioEngine;
-
-  ServicesRepository({required this.dioEngine});
-
-  Future<HttpResult<Object>> fetchPropertyNewsList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
-    Map<String, dynamic> params = {};
-
-    // if (!Utils.isEmpty(type)) {
-    //   params["type"] = type!;
-    // }
-
-    params = data!;
-
-
-    Map<String, String> headers = {};
-
-    headers["Content-Type"] = "application/x-www-form-urlencoded";
-    headers["Accept"] = "application/x.yyjobs-api.v1+json";
-
-    final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
-      '/index.php/api/employee/extra/time', // api 地址
-      params: params,
-      headers: headers,
-      method: HttpMethod.GET,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
-      cancelToken: cancelToken,
-    );
-
-    //根据返回的结果,封装原始数据为Bean/Entity对象
-    if (result.isSuccess) {
-      //重新赋值data或list
-      final json = result.getDataJson();
-      var data = ServicesState.fromJson(json!);
-      //重新赋值data或list
-      return result.convert<ServicesState>(data: data);
-    }
-    return result.convert();
-  }
-
-
-}

+ 0 - 0
packages/cpt_services/lib/modules/services/services_state.dart


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