소스 검색

update property module

glglove 2 주 전
부모
커밋
eab81cee25

+ 130 - 0
packages/cpt_property/lib/components/bottomDialog.dart

@@ -0,0 +1,130 @@
+
+import 'package:flutter/material.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/no_shadow_scroll_behavior.dart';
+import 'package:widgets/widget_export.dart';
+
+class BottomDialog extends StatelessWidget {
+  String? title;
+  String? message;
+  Widget? Function(BuildContext)? messageBuilder;
+  VoidCallback confirmAction;
+  VoidCallback? cancelAction;
+  bool isShowCancelBtn;
+  String? confirmTxt;
+  String? cancelTxt;
+  final double? minHeight;
+  final double? maxHeight;
+
+  BottomDialog({
+    this.title,
+    this.message,
+    Widget Function(BuildContext)? this.messageBuilder,
+    required this.confirmAction,
+    this.cancelAction,
+    this.isShowCancelBtn = true,
+    this.confirmTxt,
+    this.cancelTxt,
+    minHeight,
+    maxHeight,
+    Key? key,
+  }): minHeight = minHeight?? 0,
+      maxHeight = maxHeight?? 300,
+        super(key:key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      width: double.infinity,
+      padding: const EdgeInsets.only(top: 30),
+      constraints: BoxConstraints(
+        minHeight: minHeight!,
+        maxHeight: maxHeight!,
+      ),
+      decoration: BoxDecoration(
+        color: context.appColors.whiteSecondBG,
+        borderRadius: const BorderRadius.only(
+          topLeft: Radius.circular(0),
+          topRight: Radius.circular(0),
+        ),
+      ),
+      child: Column(
+        children: [
+          Scrollbar(
+            child: ScrollConfiguration(
+              behavior: NoShadowScrollBehavior(),
+              child: SingleChildScrollView(
+                child: messageBuilder?.call(context) ??
+                  MyTextView(
+                    message!,
+                    fontSize: 18,
+                    textColor: context.appColors.textBlack,
+                    isFontRegular: true,
+                    textAlign: TextAlign.center,
+                    paddingLeft: 30,
+                    paddingRight: 30,
+                  ),
+              ),
+            ),
+          ).constrained(maxHeight: maxHeight! - 60),
+          Row(
+            children: [
+              const SizedBox(width: 18),
+              Visibility(
+                visible: isShowCancelBtn,
+                child: Expanded(
+                    flex: 1,
+                    child: InkWell(
+                      onTap: () {
+                        onCancel();
+                        cancelAction?.call();
+                      },
+                      child: MyTextView(
+                        cancelTxt ?? S.current.no,
+                        fontSize: 16,
+                        isFontMedium: true,
+                        paddingTop: 13,
+                        marginRight: 15,
+                        paddingBottom: 13,
+                        textAlign: TextAlign.center,
+                        textColor: Colors.white,
+                        backgroundColor: context.appColors.orangeBG,
+                        cornerRadius: 7,
+                      ),
+                    )),
+              ),
+              Expanded(
+                  flex: 1,
+                  child: InkWell(
+                    onTap: () async {
+                      onCancel();
+                      confirmAction();
+                    },
+                    child: MyTextView(
+                      confirmTxt ?? S.current.yes,
+                      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),
+        ],
+      ),
+    );
+  }
+
+  //取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

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

@@ -1,41 +0,0 @@
-import 'package:cs_resources/generated/assets.dart';
-import 'package:flutter/material.dart';
-import 'package:auto_route/auto_route.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-import 'package:router/ext/auto_router_extensions.dart';
-import 'package:widgets/my_load_image.dart';
-
-import '../../../router/page/property_page_router.dart';
-import '../vm/property_ioan_vm.dart';
-
-@RoutePage()
-class PropertyIoanPage extends HookConsumerWidget {
-  const PropertyIoanPage({Key? key}) : super(key: key);
-
-  //启动当前页面
-  static void startInstance({BuildContext? context}) {
-    if (context != null) {
-      context.router.push(const PropertyIoanPageRoute());
-    } else {
-      appRouter.push(const PropertyIoanPageRoute());
-    }
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final _vm = ref.read(propertyIoanVmProvider.notifier);
-
-    return Scaffold(
-      // appBar: AppBar(title: Text("资产")),
-      body: Column(
-        children: [
-           MyAssetImage(
-            Assets.propertyIoan,
-            width: 100,
-            height: 100,
-          ),
-        ],
-      ),
-    );
-  }
-}

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

@@ -0,0 +1,399 @@
+import 'package:cpt_property/components/bottomDialog.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/property_page_router.dart';
+import 'property_ioan_vm.dart';
+
+@RoutePage()
+class PropertyIoanPage extends HookConsumerWidget {
+  const PropertyIoanPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const PropertyIoanPageRoute());
+    } else {
+      appRouter.push(const PropertyIoanPageRoute());
+    }
+  }
+
+  Widget _buildContentTopAdviceSection(BuildContext context,WidgetRef ref, _vm){
+    return Column(
+      children: [
+        MyTextView(
+          "YY Home",
+          textColor: ColorUtils.string2Color('#000000'),
+          fontSize: 27,
+          fontWeight: FontWeight.w500,
+          textAlign: TextAlign.center,
+        ),
+        MyTextView(
+          "Find the best home loan for you",
+          textColor: ColorUtils.string2Color('#000000'),
+          fontSize: 16,
+          fontWeight: FontWeight.w400,
+          marginBottom: 14,
+          textAlign: TextAlign.center,
+        ),
+        Container(
+          width: double.infinity,
+          height: 210,
+          decoration: BoxDecoration(
+            borderRadius: BorderRadius.circular(0),
+            color: ColorUtils.string2Color('#FEFEFE'),
+            image: const DecorationImage(
+              image: AssetImage('packages/cs_resources/${Assets.propertyHomeLoanBg}'), // 使用包中的资源
+              fit: BoxFit.cover,
+            ),
+          ),
+          child: Column(
+            children: [
+              MyTextView(
+                "YY Home exclusive rates:",
+                textColor: ColorUtils.string2Color('#FEFEFE'),
+                fontSize: 15,
+                boxWidth: 237,
+                boxHeight: 35,
+                alignment: Alignment.center,
+                textAlign: TextAlign.center,
+                marginTop: 5.5,
+                backgroundColor: ColorUtils.string2Color('#4161D0')
+              ),
+              Expanded(
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    Container(
+                        width: 105,
+                        height: 105,
+                        padding: const EdgeInsets.all(5),
+                        color: ColorUtils.string2Color('#4161D0'),
+                        child: Column(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          children: [
+                            MyTextView(
+                              _vm.state.lowestFloatingRate,
+                              textColor: ColorUtils.string2Color('#FEFEFE'),
+                              fontSize: 30,
+                            ),
+                            MyTextView(
+                              "Lowest Floating Rate",
+                              textColor: ColorUtils.string2Color('#FEFEFE'),
+                              fontSize: 14,
+                              textAlign: TextAlign.center,
+                            ),
+                          ]
+                        )
+                    ),
+                    Container(
+                        width: 105,
+                        height: 105,
+                        padding: const EdgeInsets.all(5),
+                        color: ColorUtils.string2Color('#4161D0'),
+                        margin: const EdgeInsets.only(left: 18),
+                        child: Column(
+                            mainAxisAlignment: MainAxisAlignment.center,
+                            crossAxisAlignment: CrossAxisAlignment.center,
+                            children: [
+                              MyTextView(
+                                _vm.state.lowestFixedRate,
+                                textColor: ColorUtils.string2Color('#FEFEFE'),
+                                fontSize: 30,
+                              ),
+                              MyTextView(
+                                "Lowest Floating Rate",
+                                textColor: ColorUtils.string2Color('#FEFEFE'),
+                                fontSize: 14,
+                                textAlign: TextAlign.center,
+                              ),
+                            ]
+                        )
+                    ),
+                  ],
+                ),
+              ),
+            ],
+          ),
+        ),
+        MyTextView(
+          "Check out what others are offering:",
+          textColor: ColorUtils.string2Color('#FEFEFE'),
+          fontSize: 15,
+          boxWidth: double.infinity,
+          boxHeight: 40.5,
+          alignment: Alignment.center,
+          textAlign: TextAlign.center,
+          backgroundColor: ColorUtils.string2Color('#4161D0'),
+        ),
+
+        const SizedBox(height: 20),
+
+        Row(
+          mainAxisAlignment: MainAxisAlignment.start,
+          children: [
+            MyLoadImage(
+              Assets.propertyAdvicePic,
+              width: 132,
+              // height: 122.5,
+            ),
+            Expanded(
+              child: Container(
+                // color: Colors.red,
+                padding: const EdgeInsets.only(left: 50,right: 20),
+                child: Column(
+                  // mainAxisAlignment: MainAxisAlignment.end,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        MyTextView(
+                          "Floating",
+                          textColor: ColorUtils.string2Color('#000000'),
+                          fontSize: 14,
+                          textAlign: TextAlign.center,
+                        ),
+                        MyTextView(
+                          "Fixed",
+                          textColor: ColorUtils.string2Color('#000000'),
+                          fontSize: 14,
+                          textAlign: TextAlign.center,
+                          marginLeft: 47.5,
+                        ),
+                      ],
+                    ),
+                    // const SizedBox(height: 10),
+
+                    Expanded(child: Column(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Row(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          children: [
+                            MyTextView(
+                              "3.08%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 20,
+                            ),
+                            MyTextView(
+                              "2.50%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 47.5,
+                            ),
+                          ],
+                        ),
+                        Row(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          children: [
+                            MyTextView(
+                              "3.08%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 20,
+                            ),
+                            MyTextView(
+                              "2.50%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 47.5,
+                            ),
+                          ],
+                        ).marginOnly(top: 15),
+                        Row(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          children: [
+                            MyTextView(
+                              "3.08%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 20,
+                            ),
+                            MyTextView(
+                              "2.50%",
+                              textColor: ColorUtils.string2Color('#000000'),
+                              fontSize: 16,
+                              textAlign: TextAlign.center,
+                              fontWeight: FontWeight.w500,
+                              marginLeft: 47.5,
+                            ),
+                          ],
+                        ).marginOnly(top: 15),
+                      ],
+                    ))
+
+
+                  ],
+                ),
+              ),
+            ),
+          ],
+        ).constrained(height: 160),
+      ],
+    );
+  }
+
+  Widget _buildContentMiddleTextSection(BuildContext context,WidgetRef ref, _vm) {
+    return Column(
+        children: [
+          MyTextView(
+            "The right advice to help you choose the best package in the market!",
+            textColor: ColorUtils.string2Color('#000000'),
+            fontSize: 18,
+            fontWeight: FontWeight.w500,
+            marginTop: 20,
+            marginBottom: 20,
+            textAlign: TextAlign.center,
+          ),
+          MyTextView(
+            "-No Hidden Fees, We Are Out ToHelp You!-Interest Savings With Lowest RatesGuarantee-One-Stop Access to All The BanksPackages",
+            textColor: ColorUtils.string2Color('#000000'),
+            fontSize: 15,
+            textAlign: TextAlign.center,
+            marginBottom: 20,
+          ),
+        ],
+    );
+  }
+
+  Widget _buildContentOfferSection(BuildContext context,WidgetRef ref, _vm) {
+    final offerTextInfoList = _vm.state.offerTextInfoList.map((value) => value).toList();
+    return Container(
+      width: double.infinity,
+      child: Column(
+        children: [
+          MyTextView(
+           "What do we offer?",
+            textColor: ColorUtils.string2Color('#000000'),
+            fontSize: 18,
+            fontWeight: FontWeight.w500,
+            marginTop: 16.5,
+            marginBottom: 16.5,
+          ),
+          Wrap(
+            children: List.generate(offerTextInfoList.length, (index){
+              return Container(
+                width: MediaQuery.of(context).size.width / 2 - 100,
+                margin: const EdgeInsets.only(right: 15,bottom: 15),
+                padding: const EdgeInsets.only(left: 15,right: 15,top:15,bottom:15,),
+                // decoration: BoxDecoration(
+                //   borderRadius: BorderRadius.circular(10),
+                //   color: ColorUtils.string2Color('#F5F5F5'),
+                // ),
+                child: Column(
+                  children: [
+                    MyLoadImage(
+                      offerTextInfoList[index]["icon"],
+                      width: offerTextInfoList[index]["iconWidth"],
+                      height: offerTextInfoList[index]["iconHeight"],
+                    ),
+                    const SizedBox(height: 13,),
+                    MyTextView(
+                      offerTextInfoList[index]["title"],
+                      fontSize: 15,
+                      textColor: ColorUtils.string2Color('#000000'),
+                      textAlign: TextAlign.center,
+                    ),
+                  ]
+                ),
+              );
+            }),
+          ),
+        ]
+      ),
+    );
+  }
+
+  Widget _buildContentBottomPartnersSection(BuildContext context,WidgetRef ref, _vm) {
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        MyTextView(
+          "Our Partners",
+          textColor: ColorUtils.string2Color('#000000'),
+          fontSize: 18,
+          fontWeight: FontWeight.w500,
+          marginBottom: 16.5,
+        ),
+        MyLoadImage(Assets.propertyOurPartners,),
+      ],
+    );
+  }
+
+  Widget _buildCotentBox(BuildContext context,WidgetRef ref, _vm) {
+    return Column(
+      children: [
+        _buildContentTopAdviceSection(context, ref, _vm),
+        const SizedBox(height: 15,),
+        _buildContentMiddleTextSection(context, ref, _vm),
+        const SizedBox(height: 15,),
+        _buildContentOfferSection(context, ref, _vm),
+        const SizedBox(height: 15,),
+        _buildContentBottomPartnersSection(context, ref, _vm),
+      ],
+    );
+  }
+
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(propertyIoanVmProvider.notifier);
+
+    return Scaffold(
+      backgroundColor: ColorUtils.string2Color("#F2F3F6"),
+      // appBar: AppBar(title: Text("资产")),
+      body: Column(
+        children: [
+          Expanded(
+            child: SingleChildScrollView(
+              child: Padding(
+                  padding: const EdgeInsets.only(left: 15,right: 15,top: 15),
+                  child: _buildCotentBox(context, ref, _vm),
+              )
+            )
+          ),
+          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,
+                ),
+              ],
+            ),
+          ).onTap((){
+            _vm.handlerRequestQuote(context);
+          })
+        ],
+      ),
+    );
+  }
+}

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

@@ -0,0 +1,39 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+PropertyIoanState propertyIoanStateFromJson(String str) => PropertyIoanState.fromJson(json.decode(str));
+
+String propertyIoanStateToJson(PropertyIoanState data) => json.encode(data.toJson());
+
+class PropertyIoanState {
+    PropertyIoanState({
+        required this.offerTextInfoList,
+        required this.lowestFloatingRate,
+        required this.othersOfferingPic,
+        required this.lowestFixedRate,
+        required this.othersOfferingInfoList,
+    });
+
+    List<dynamic> offerTextInfoList;
+    String lowestFloatingRate;
+    String othersOfferingPic;
+    String lowestFixedRate;
+    List<dynamic> othersOfferingInfoList;
+
+    factory PropertyIoanState.fromJson(Map<dynamic, dynamic> json) => PropertyIoanState(
+        offerTextInfoList: List<dynamic>.from(json["offerTextInfoList"].map((x) => x)),
+        lowestFloatingRate: json["lowestFloatingRate"],
+        othersOfferingPic: json["othersOfferingPic"],
+        lowestFixedRate: json["lowestFixedRate"],
+        othersOfferingInfoList: List<dynamic>.from(json["othersOfferingInfoList"].map((x) => x)),
+    );
+
+    Map<dynamic, dynamic> toJson() => {
+        "offerTextInfoList": List<dynamic>.from(offerTextInfoList.map((x) => x)),
+        "lowestFloatingRate": lowestFloatingRate,
+        "othersOfferingPic": othersOfferingPic,
+        "lowestFixedRate": lowestFixedRate,
+        "othersOfferingInfoList": List<dynamic>.from(othersOfferingInfoList.map((x) => x)),
+    };
+}

+ 137 - 0
packages/cpt_property/lib/modules/ioan/property_ioan_vm.dart

@@ -0,0 +1,137 @@
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/my_text_view.dart';
+import '../../components/bottomDialog.dart';
+import './property_ioan_state.dart';
+
+part 'property_ioan_vm.g.dart';
+
+@riverpod
+class PropertyIoanVm extends _$PropertyIoanVm {
+  PropertyIoanState initState() {
+    return PropertyIoanState(
+        lowestFloatingRate: "3.79%",
+        lowestFixedRate: "2.48%",
+        othersOfferingPic: "",
+        othersOfferingInfoList: [
+          {
+            "floating": "3.08%",
+            "fixed": "3.79%",
+          },
+          {
+            "floating": "3.08%",
+            "fixed": "3.79%",
+          }
+        ],
+        offerTextInfoList: [
+            {
+              "title": "New HomeLoans",
+              "icon": Assets.propertyNewHomeLoans,
+              "iconWidth": 46.0,
+              "iconHeight": 42.5
+            },
+            {
+              "title": "Refinancing",
+              "icon": Assets.propertyRefinancing,
+              "iconWidth": 37.0,
+              "iconHeight": 41.5
+            },
+            {
+              "title": "Home EquityLoans",
+              "icon": Assets.propertyHomeEquityLoans,
+              "iconWidth": 41.5,
+              "iconHeight": 42.5
+            },
+            {
+              "title": "ConveyancingLawyer",
+              "icon": Assets.propertyConveyancingLawyer,
+              "iconWidth": 42.0,
+              "iconHeight": 42.0
+            },
+            {
+              "title": "Approval in Principle",
+              "icon": Assets.propertyApproval,
+              "iconWidth": 41.0,
+              "iconHeight": 39.0
+            },
+            {
+              "title": "OverseasHome Loan",
+              "icon": Assets.propertyOverseasHomeLoan,
+              "iconWidth": 36.0,
+              "iconHeight": 39.0
+            }
+        ]
+    );
+  }
+
+  @override
+  PropertyIoanState build(){
+    // 引入数据仓库
+    // propertyIoanRepository = ref.read(propertyIoanRepositoryProvider);
+    // 初始化状态
+    PropertyIoanState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  requestQuoteConfirmAction(){
+    Log.d("点击了确定");
+    DialogEngine.dismiss(tag: "requestQuote");
+  }
+
+  requestQuoteCancelAction(){
+    Log.d("点击了取消");
+  }
+
+  handlerRequestQuote(BuildContext context) async {
+    Log.d("点击了请求报价");
+    ToastEngine.show("暂未开放");
+    await DialogEngine.show(
+      tag: "requestQuote",
+      position: DialogPosition.bottom,
+      widget: BottomDialog(
+        confirmAction: requestQuoteConfirmAction,
+        cancelAction: requestQuoteCancelAction,
+        messageBuilder: (context) {
+          return Container(
+            padding: const EdgeInsets.only(left: 15,right: 15),
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.start,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                MyTextView(
+                  "Submit Request?",
+                  textColor: ColorUtils.string2Color('#000000'),
+                  textAlign: TextAlign.left,
+                  fontWeight: FontWeight.w500,
+                  fontSize: 21,
+                  // maxLines: 5,
+                  marginBottom: 20,
+                ),
+                MyTextView(
+                  "A mortgage specialist will be incontact to help you compare theatest housing loan rates and tosecure the best package that suitsyour need",
+                  textColor: ColorUtils.string2Color('#666666'),
+                  textAlign: TextAlign.left,
+                  // maxLines: 5,
+                ),
+                MyTextView(
+                  "This is a complementary servicebrought to you by YY Home",
+                  textColor: ColorUtils.string2Color('#666666'),
+                  textAlign: TextAlign.left,
+                  // maxLines: 5,
+                  marginTop: 15,
+                ),
+              ]
+            )
+          );
+        },
+      ),
+    );
+  }
+}

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

@@ -6,12 +6,12 @@ part of 'property_ioan_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$propertyIoanVmHash() => r'e543d5bc121950c3301766873f79a84632d07887';
+String _$propertyIoanVmHash() => r'0a144f8492752958fa349425ff3a3e2fe631b733';
 
 /// See also [PropertyIoanVm].
 @ProviderFor(PropertyIoanVm)
 final propertyIoanVmProvider =
-    AutoDisposeNotifierProvider<PropertyIoanVm, void>.internal(
+    AutoDisposeNotifierProvider<PropertyIoanVm, PropertyIoanState>.internal(
   PropertyIoanVm.new,
   name: r'propertyIoanVmProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -21,6 +21,6 @@ final propertyIoanVmProvider =
   allTransitiveDependencies: null,
 );
 
-typedef _$PropertyIoanVm = AutoDisposeNotifier<void>;
+typedef _$PropertyIoanVm = AutoDisposeNotifier<PropertyIoanState>;
 // ignore_for_file: type=lint
 // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 0 - 14
packages/cpt_property/lib/modules/ioan/vm/property_ioan_vm.dart

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

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

@@ -30,7 +30,7 @@ class PropertyNewsPage extends HookConsumerWidget {
     return Container(
       // color: Colors.blue,
       width: 100,
-      height: 117.5,
+      // height: 117.5,
       child: Center(
         child: MyLoadImage(
           item['pic'],
@@ -39,7 +39,9 @@ class PropertyNewsPage extends HookConsumerWidget {
           height: 50.5,
         ),
       )
-    ).marginOnly(right: 17.5);
+    ).marginOnly(right: 17.5).constrained(
+      minHeight: 117.5,
+    );
   }
 
   Widget _buildItemRightSection(BuildContext context,WidgetRef ref, item, _vm) {
@@ -55,7 +57,7 @@ class PropertyNewsPage extends HookConsumerWidget {
 
     return Container(
       color: Colors.white,
-      padding: const EdgeInsets.only(top: 10.5, bottom: 10.5),
+      padding: const EdgeInsets.only(left:5, top: 10.5, bottom: 10.5),
       child: Container(
         child: Stack(
           children: [
@@ -112,6 +114,8 @@ class PropertyNewsPage extends HookConsumerWidget {
               }),
             ),
           ],
+        ).constrained(
+          minHeight: 96.5,
         ),
       ),
     );

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

@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/color_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
 
 import '../../../router/page/property_page_router.dart';
 import '../vm/property_vm.dart';
@@ -25,6 +27,8 @@ class PropertyPage extends HookConsumerWidget {
   // 顶部tab 切换
   Widget _buildTopSection(BuildContext context, WidgetRef ref, _vm) {
     final topSectionsData = _vm.topSectionsData;
+    // 监听 curIdx 的变化
+    final curIdx = ref.watch(propertyVmProvider.select((value) => value.curIdx));
     return Container(
       color: Colors.white,
       child: Center(
@@ -52,7 +56,11 @@ class PropertyPage extends HookConsumerWidget {
                     item['title'],
                     maxLines: 1, // 设置最大行数为2
                     overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
-                    style: const TextStyle(fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w500), // 设置字体大小
+                    style: TextStyle(
+                        fontSize: 13.0,
+                        color: curIdx == index ? ColorUtils.string2Color('#4161D0'):Colors.black,
+                        fontWeight: FontWeight.w500
+                    ), // 设置字体大小
                   ),
                 ],
               ),

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

@@ -1,10 +1,11 @@
 
 import 'package:cs_resources/generated/assets.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 
-import '../../ioan/page/property_ioan_page.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';
@@ -13,16 +14,46 @@ part 'property_vm.g.dart';
 
 
 class PropertyVmState {
-  List<Map<String, dynamic>> topSectionsData;
+  List<Map<String, dynamic>>? topSectionsData;
+  int? curIdx;
+
   PropertyVmState({
-    required this.topSectionsData,
-  });
+    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({
-    required List<Map<String, dynamic>> topSectionsData,
-  }){
+  PropertyVmState copyWith({
+    List<Map<String, dynamic>>? topSectionsData,
+    int? curIdx = 0,
+  }) {
     return PropertyVmState(
       topSectionsData: topSectionsData ?? this.topSectionsData,
+      curIdx: curIdx ?? 0,
     );
   }
 }
@@ -32,48 +63,39 @@ class PropertyVm extends _$PropertyVm {
   get topSectionsData => state.topSectionsData;
 
   PropertyVmState initState() {
-    return PropertyVmState(
-      topSectionsData: [
-        {
-          "title": "Sale",
-          "icon": Assets.propertySale,
-          "pageStartInstanceFn": PropertySalePage.startInstance,
-          "page": const PropertySalePage(),
-        },
-        {
-          "title": "Rent",
-          "icon": Assets.propertyRent,
-          "pageStartInstanceFn": PropertyRentPage.startInstance,
-          "page": const PropertyRentPage(),
-        },
-        {
-          "title": "Ioan",
-          "icon": Assets.propertyIoan,
-          "pageStartInstanceFn": PropertyIoanPage.startInstance,
-          "page": const PropertyIoanPage(),
-        },
-        {
-          "title": "News",
-          "icon": Assets.propertyNews,
-          "pageStartInstanceFn": PropertyNewsPage.startInstance,
-          "page": const PropertyNewsPage(),
-        }
-      ],
-    );
+    return PropertyVmState();
   }
 
   @override
   PropertyVmState build(){
     final state = initState();
+    Log.d("--------------------------build---------------------");
+
+    // 初始时导航到子路由
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      switchPage(state.curIdx ?? 0, null, true);
+    });
+
     return state;
   }
 
   // 页面切换
-  switchPage(int index, context){
-    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);
+  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);
+      }
+    }
   }
 
 }
+

+ 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'2d8b2322ab1a903277de8ede5fc484003e901dc8';
+String _$propertyVmHash() => r'9b08b5e83d2b45f67b653daf60bb66bacb9c47ed';
 
 /// See also [PropertyVm].
 @ProviderFor(PropertyVm)

+ 1 - 1
packages/cpt_property/lib/router/page/property_page_router.dart

@@ -4,7 +4,7 @@ import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 
 import '../../modules/property/page/property_page.dart';
-import '../../modules/ioan/page/property_ioan_page.dart';
+import '../../modules/ioan/property_ioan_page.dart';
 import '../../modules/news/page/property_news_page.dart';
 import '../../modules/news_detail/property_news_detail_page.dart';
 import '../../modules/sale/page/property_sale_page.dart';