Browse Source

Merge remote-tracking branch 'origin/dev_services' into dev_services

# Conflicts:
#	packages/cs_domain/lib/generated/json/base/json_convert_content.dart
liukai 2 months ago
parent
commit
da5a00fb0e
90 changed files with 4007 additions and 1654 deletions
  1. 2 2
      packages/cpt_community/lib/modules/garage/garagesale_detail/garagesale_detail_vm.dart
  2. 3 0
      packages/cpt_profile/lib/modules/setting/setting_view_model.dart
  3. 12 5
      packages/cpt_services/lib/components/chooseAirConditionContent.dart
  4. 9 2
      packages/cpt_services/lib/components/chooseAirConditionContent_state.dart
  5. 60 37
      packages/cpt_services/lib/components/chooseAirConditionContent_vm.dart
  6. 1 1
      packages/cpt_services/lib/components/chooseAirConditionContent_vm.g.dart
  7. 12 4
      packages/cpt_services/lib/components/chooseAirConditionTitle.dart
  8. 19 16
      packages/cpt_services/lib/components/chooseHouseCleanContent.dart
  9. 10 7
      packages/cpt_services/lib/components/chooseHouseCleanContent_state.dart
  10. 59 66
      packages/cpt_services/lib/components/chooseHouseCleanContent_vm.dart
  11. 1 1
      packages/cpt_services/lib/components/chooseHouseCleanContent_vm.g.dart
  12. 8 4
      packages/cpt_services/lib/components/chooseHouseCleanTitle.dart
  13. 7 5
      packages/cpt_services/lib/components/chooseVisitTimeBottomFooter.dart
  14. 22 4
      packages/cpt_services/lib/components/chooseVisitTimeBottomFooter_vm.dart
  15. 1 1
      packages/cpt_services/lib/components/chooseVisitTimeBottomFooter_vm.g.dart
  16. 61 30
      packages/cpt_services/lib/components/chooseVisitTimeContent.dart
  17. 41 22
      packages/cpt_services/lib/components/chooseVisitTimeContent_state.dart
  18. 97 241
      packages/cpt_services/lib/components/chooseVisitTimeContent_vm.dart
  19. 1 1
      packages/cpt_services/lib/components/chooseVisitTimeContent_vm.g.dart
  20. 2 11
      packages/cpt_services/lib/components/chooseVisitTimeTitle.dart
  21. 13 8
      packages/cpt_services/lib/components/chooseVisitTimeTitle_state.dart
  22. 41 18
      packages/cpt_services/lib/components/chooseVisitTimeTitle_vm.dart
  23. 1 1
      packages/cpt_services/lib/components/chooseVisitTimeTitle_vm.g.dart
  24. 3 3
      packages/cpt_services/lib/components/repair_status_card_item.dart
  25. 4 4
      packages/cpt_services/lib/components/status_card_item_vm.dart
  26. 1 1
      packages/cpt_services/lib/components/status_card_item_vm.g.dart
  27. 10 10
      packages/cpt_services/lib/constants_services.dart
  28. 11 11
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_page.dart
  29. 6 6
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_vm.dart
  30. 1 1
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_vm.g.dart
  31. 5 5
      packages/cpt_services/lib/modules/services/history/history_page.dart
  32. 2 2
      packages/cpt_services/lib/modules/services/history/history_vm.dart
  33. 1 1
      packages/cpt_services/lib/modules/services/history/history_vm.g.dart
  34. 12 7
      packages/cpt_services/lib/modules/services/homeService/home_service_page.dart
  35. 5 4
      packages/cpt_services/lib/modules/services/homeService/home_service_state.dart
  36. 129 122
      packages/cpt_services/lib/modules/services/homeService/home_service_vm.dart
  37. 1 1
      packages/cpt_services/lib/modules/services/homeService/home_service_vm.g.dart
  38. 23 22
      packages/cpt_services/lib/modules/services/homeService/service_card_item.dart
  39. 5 5
      packages/cpt_services/lib/modules/services/inProgress/in_progress_page.dart
  40. 2 2
      packages/cpt_services/lib/modules/services/inProgress/in_progress_vm.dart
  41. 1 1
      packages/cpt_services/lib/modules/services/inProgress/in_progress_vm.g.dart
  42. 5 4
      packages/cpt_services/lib/modules/services/repair/repair_page.dart
  43. 5 5
      packages/cpt_services/lib/modules/services/repair_history/history_page.dart
  44. 2 2
      packages/cpt_services/lib/modules/services/repair_history/history_vm.dart
  45. 1 1
      packages/cpt_services/lib/modules/services/repair_history/history_vm.g.dart
  46. 1 1
      packages/cpt_services/lib/modules/services/repair_homeService/home_service_page.dart
  47. 47 51
      packages/cpt_services/lib/modules/services/repair_homeService/home_service_vm.dart
  48. 1 1
      packages/cpt_services/lib/modules/services/repair_homeService/home_service_vm.g.dart
  49. 5 5
      packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_page.dart
  50. 2 2
      packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_vm.dart
  51. 1 1
      packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_vm.g.dart
  52. 140 138
      packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_page.dart
  53. 3 2
      packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_state.dart
  54. 61 63
      packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_vm.dart
  55. 1 1
      packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_vm.g.dart
  56. 5 5
      packages/cpt_services/lib/modules/services/service_evaluate_create/service_evaluate_create_page.dart
  57. 1 1
      packages/cpt_services/lib/modules/services/service_evaluate_create/service_evaluate_create_vm.g.dart
  58. 6 7
      packages/cpt_services/lib/modules/services/service_evaluate_list/service_evaluate_list_page.dart
  59. 1 1
      packages/cpt_services/lib/modules/services/service_evaluate_list/service_evaluate_list_vm.g.dart
  60. 187 99
      packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_page.dart
  61. 13 3
      packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_state.dart
  62. 187 129
      packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_vm.dart
  63. 1 1
      packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_vm.g.dart
  64. 3 7
      packages/cpt_services/lib/modules/services/service_pay_success/service_pay_success_page.dart
  65. 1 1
      packages/cpt_services/lib/modules/services/service_repair_detail/service_repair_detail_vm.dart
  66. 1 1
      packages/cpt_services/lib/modules/services/service_repair_detail/service_repair_detail_vm.g.dart
  67. 92 45
      packages/cpt_services/lib/modules/services/services_main_page.dart
  68. 35 0
      packages/cpt_services/lib/modules/services/services_main_state.dart
  69. 163 0
      packages/cpt_services/lib/modules/services/services_main_vm.dart
  70. 26 0
      packages/cpt_services/lib/modules/services/services_main_vm.g.dart
  71. 7 4
      packages/cpt_services/lib/modules/services/services_page.dart
  72. 5 1
      packages/cpt_services/lib/modules/services/services_state.dart
  73. 18 1
      packages/cpt_services/lib/modules/services/services_vm.dart
  74. 1 1
      packages/cpt_services/lib/modules/services/services_vm.g.dart
  75. 51 12
      packages/cpt_services/lib/respository/services_respository.dart
  76. 73 86
      packages/cpt_services/lib/router/page/services_page_router.gr.dart
  77. 137 0
      packages/cs_domain/lib/entity/paid_service_detail_entity.dart
  78. 85 0
      packages/cs_domain/lib/entity/paid_service_entity.dart
  79. 169 0
      packages/cs_domain/lib/entity/paid_service_pay_success_info_entity.dart
  80. 24 0
      packages/cs_domain/lib/entity/service_category_entity.dart
  81. 26 0
      packages/cs_domain/lib/entity/service_time_period_entity.dart
  82. 458 172
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  83. 374 0
      packages/cs_domain/lib/generated/json/paid_service_detail_entity.g.dart
  84. 206 0
      packages/cs_domain/lib/generated/json/paid_service_entity.g.dart
  85. 410 0
      packages/cs_domain/lib/generated/json/paid_service_pay_success_info_entity.g.dart
  86. 49 0
      packages/cs_domain/lib/generated/json/service_category_entity.g.dart
  87. 63 0
      packages/cs_domain/lib/generated/json/service_time_period_entity.g.dart
  88. 2 0
      packages/cs_plugin_basic/lib/constants/app_constant.dart
  89. 28 0
      packages/cs_shared/lib/utils/richText_utils.dart
  90. 119 105
      packages/cs_widgets/lib/dialog/dialog_content_wrap.dart

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

@@ -208,8 +208,8 @@ class GaragesaleDetailVm extends _$GaragesaleDetailVm {
   }
   // 点击 whatsapp
   handlerClickWhatsapp(BuildContext? context,String contactType, String title, int price){
-    // 假设你有一个获取 WhatsApp 号码的方法
-    String whatsappNumber = getContactNumber(contactType); // 你需要实现这个方法
+    // 获取 WhatsApp 号码
+    String whatsappNumber = getContactNumber(contactType); 
     // 构建消息并进行编码
     String message = Uri.encodeComponent("Hello, I am interested in your listing: $title for $price.");
     // 打开WhatsApp

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

@@ -44,6 +44,9 @@ class SettingViewModel extends _$SettingViewModel {
         UserConfigService.getInstance().handleLogoutParams();
         // 清除 garagesale category 缓存
         SPUtil.remove(AppConstant.storageGarageCategoryList);
+        // 清除 servives category 缓存
+        SPUtil.remove(AppConstant.storagePaidServiceCategoryList);
+        SPUtil.remove(AppConstant.storageRepairServiceCategoryList);
         //清除全部页面栈去登录页面
         ComponentServiceManager().authService.startAndPopAllLoginPage();
       },

+ 12 - 5
packages/cpt_services/lib/components/chooseAirConditionContent.dart

@@ -2,6 +2,7 @@
 import 'package:cpt_services/components/chooseAirConditionContent_vm.dart';
 import 'package:cpt_services/components/status_card_item.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -15,18 +16,24 @@ import 'chooseAirConditionContent_vm.dart';
 
 class ChooseAirConditionContent extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
+  final List<PaidServiceDetailProducts> products;
 
-  const ChooseAirConditionContent({Key? key,required this.id, required this.serviceTypeCode}) : super(key: key);
+  const ChooseAirConditionContent({Key? key,required this.id, required this.cleanServiceType, required this.products}) : super(key: key);
   
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(chooseAirConditionContentVmProvider.notifier);
     final state = ref.watch(chooseAirConditionContentVmProvider);
 
-    final totalPrice = ref.watch(chooseAirConditionContentVmProvider.select((state)=>state.totalPrice));
+    // final totalPrice = ref.watch(chooseAirConditionContentVmProvider.select((state)=>state.totalPrice));
 
     useEffect((){
+      vm.setInitPageData(context, {
+        'id': id,
+        'cleanServiceType': cleanServiceType,
+        'products': products,
+      });
       // 组件挂载时执行 - 执行接口请求
       // Future.microtask(() => vm.initPageData());
       return () {
@@ -38,12 +45,12 @@ class ChooseAirConditionContent extends HookConsumerWidget {
         mainAxisAlignment: MainAxisAlignment.start,
         crossAxisAlignment: CrossAxisAlignment.start,
         children: List.generate(state.airConditionList.length, (index){
-          return _buildItem(context, state.airConditionList[index], index, vm, totalPrice);
+          return _buildItem(context, state.airConditionList[index], index, vm,);
         }),
     );
   }
 
-  Widget _buildItem(BuildContext context, AirConditionContentItem airConditionItem, int index, ChooseAirConditionContentVm vm,double totalPrice){
+  Widget _buildItem(BuildContext context, AirConditionContentItem airConditionItem, int index, ChooseAirConditionContentVm vm){
     final title = airConditionItem.name??'';
     final num = airConditionItem.num?? 1;
     final price = airConditionItem.price?? 0;

+ 9 - 2
packages/cpt_services/lib/components/chooseAirConditionContent_state.dart

@@ -1,6 +1,13 @@
 class ChooseAirConditionContentState{
-  // 设置一个get  totalPrice
-  get totalPrice => airConditionList.map((item) => (item.num??0) * (item.price??0)).reduce((before, current) => before + current);
+  //  totalPrice
+  get totalPrice {
+    final prices = checkedServiceList?.map((item) => (item.num ?? 0) * (item.price ?? 0)).toList();
+    return prices?.isNotEmpty == true ? prices?.reduce((before, current) => before + current) : 0;
+  }
+  get checkedServiceList => airConditionList?.where((item) => ((item.num??0)>0? true:false))?.toList() ?? [];
+  // hasCheckdService
+  get hasCheckdService => checkedServiceList?.any((item) => ((item.num??0)>0? true:false)) ?? false;
+
   List<AirConditionContentItem> airConditionList = [];
 
   ChooseAirConditionContentState({

+ 60 - 37
packages/cpt_services/lib/components/chooseAirConditionContent_vm.dart

@@ -1,4 +1,5 @@
 
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -13,48 +14,40 @@ import 'chooseAirConditionContent_state.dart';
 part 'chooseAirConditionContent_vm.g.dart';
 
 
-List<Map<String, dynamic>> airConditionList = [
-  {
-    "name": "Hanging air conditioner (unit)",
-    "id": 1,
-    "price": 40.0,
-  },
-  {
-    "name": "Cabinet air conditioner (unit)",
-    "id": 2,
-    "price": 50.0,
-  },
-  {
-    "name": "Cylindrical air conditioner (unit)",
-    "id": 3,
-    "price": 60.0,
-  },
-  {
-    "name": "Central air conditioning (group)",
-    "id": 4,
-    "price": 70.0,
-  },
-];
-
-
-
-
-ChooseAirConditionContentState initState(){
-  Log.d("--------------------------initState---------------------");
-  List<AirConditionContentItem> airConditionListNew = [];
-  airConditionList.forEach((item) {
-    AirConditionContentItem newItem = AirConditionContentItem()..id = item['id']..price = item['price'] as double..name = item['name']..num = 1;
-    airConditionListNew.add(newItem);
-  });
-  return ChooseAirConditionContentState(
-    airConditionList: airConditionListNew,
-  );
-}
 
 @riverpod
 class ChooseAirConditionContentVm extends _$ChooseAirConditionContentVm {
   late ServicesRespository serviceRespositoryInstance;
 
+  List<PaidServiceDetailProducts> _products = [];
+
+  List<Map<String, dynamic>> airConditionList = [];
+
+
+
+  ChooseAirConditionContentState initState(){
+    Log.d("--------------------------initState---------------------");
+    if(airConditionList.isNotEmpty){
+      List<AirConditionContentItem> airConditionListNew = [];
+      airConditionList.forEach((item) {
+        AirConditionContentItem newItem = AirConditionContentItem()
+          ..id = item['id']
+          ..price = double.tryParse(item['price'] ?? '')
+          ..name = item['name']
+          ..num = 1;
+        airConditionListNew.add(newItem);
+      });
+      return ChooseAirConditionContentState(
+        airConditionList: airConditionListNew,
+      );
+    }else {
+      return ChooseAirConditionContentState(
+        airConditionList: [],
+      );
+    }
+
+  }
+
   @override
   ChooseAirConditionContentState build(){
     // 引入数据仓库
@@ -66,6 +59,36 @@ class ChooseAirConditionContentVm extends _$ChooseAirConditionContentVm {
   }
 
 
+
+  setInitPageData(BuildContext context, Map<String, dynamic>? params){
+    Log.d("--------------------------setInitPageData----------$params-----------");
+    _products = params?['products']??[];
+
+    // 渲染一帧后
+    WidgetsBinding.instance.addPostFrameCallback((_){
+      // 修改 state 中 HouseCleanList
+      if(_products != null){
+        if(_products != null && _products.isNotEmpty){
+          List<PaidServiceDetailProducts> products = _products;
+          List<AirConditionContentItem> airConditionListNew = [];
+          products.forEach((item) {
+            AirConditionContentItem newItem = AirConditionContentItem()
+              ..id = item.id
+              ..price = (item.price ?? 0.0).toDouble()
+              ..name = item.name
+              ..num = 1;
+            airConditionListNew.add(newItem);
+          });
+
+          state = state.copyWith(
+            airConditionList: airConditionListNew,
+          );
+        }
+      }
+    });
+  }
+
+
   handlerChangeNum(BuildContext context, int num, int index){
     state.airConditionList[index].num = num;
     state = state.copyWith(

+ 1 - 1
packages/cpt_services/lib/components/chooseAirConditionContent_vm.g.dart

@@ -7,7 +7,7 @@ part of 'chooseAirConditionContent_vm.dart';
 // **************************************************************************
 
 String _$chooseAirConditionContentVmHash() =>
-    r'fa5791b94a90ea6ee0aeab7895adf8b7e4ecb61a';
+    r'54d8f91a4ffe39cc789fd1500b4a8e37b4e0a5b0';
 
 /// See also [ChooseAirConditionContentVm].
 @ProviderFor(ChooseAirConditionContentVm)

+ 12 - 4
packages/cpt_services/lib/components/chooseAirConditionTitle.dart

@@ -15,14 +15,22 @@ import 'chooseAirConditionContent_vm.dart';
 
 class ChooseAirConditionTitle extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   const ChooseAirConditionTitle(
-      {Key? key,required this.id, required this.serviceTypeCode,}) : super(key: key);
+      {Key? key,required this.id, required this.cleanServiceType,}) : super(key: key);
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final totalPrice = ref.watch(chooseAirConditionContentVmProvider.select((state)=>state.totalPrice));
+    final totalPrice = useState<double>(0.0);
+    ref.listen(
+      chooseAirConditionContentVmProvider.select((state) => state.totalPrice ?? 0.0),
+          (previous, next) {
+          // 处理 totalPrice 变化
+          // print('Total Price: $next');
+          totalPrice.value = next.toDouble();
+      },
+    );
 
     useEffect((){
       // 组件挂载时执行 - 执行接口请求
@@ -50,7 +58,7 @@ class ChooseAirConditionTitle extends HookConsumerWidget {
                   // maxLines: 5,
                 ),
                 MyTextView(
-                  "\$$totalPrice",
+                  "\$${totalPrice.value}",
                   textColor: context.appColors.textPrimary,
                   textAlign: TextAlign.left,
                   isFontMedium: true,

+ 19 - 16
packages/cpt_services/lib/components/chooseHouseCleanContent.dart

@@ -1,6 +1,7 @@
 
 import 'package:cpt_services/components/status_card_item.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -16,22 +17,22 @@ import 'chooseHouseCleanContent_vm.dart';
 
 class ChooseHouseCleanContent extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
   final String? useScence;
+  final List<PaidServiceDetailProducts> products;
 
-  const ChooseHouseCleanContent({Key? key,required this.id, required this.serviceTypeCode, this.useScence}) : super(key: key);
+  const ChooseHouseCleanContent({Key? key,required this.id, required this.cleanServiceType, required this.products, this.useScence}) : super(key: key);
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(chooseHouseCleanContentVmProvider.notifier);
-    final state = ref.watch(chooseHouseCleanContentVmProvider);
-
-    final totalPrice = ref.watch(chooseHouseCleanContentVmProvider.select((state)=>state.totalPrice));
+    List<HouseCleanContentItem>? houseCleanList = ref.watch(chooseHouseCleanContentVmProvider.select((state) => state.houseCleanList));
 
     useEffect((){
       vm.setInitPageData(context, {
         'id': id,
-        'serviceTypeCode': serviceTypeCode,
+        'cleanServiceType': cleanServiceType,
+        'products': products,
         'useScence': useScence,
       });
       // 组件挂载时执行 - 执行接口请求
@@ -46,9 +47,12 @@ class ChooseHouseCleanContent extends HookConsumerWidget {
       child: Column(
         mainAxisAlignment: MainAxisAlignment.start,
         crossAxisAlignment: CrossAxisAlignment.start,
-        children: List.generate(state.HouseCleanList.length, (index){
-          return _buildItem(context, state.HouseCleanList[index], index, vm);
-        }),
+        children:  houseCleanList != null && houseCleanList.isNotEmpty? List.generate(houseCleanList!.length, (index){
+          HouseCleanContentItem currentItem = houseCleanList![index];
+          // 如何用ref  去watch  state中的 houseCleanList中的第index 变化
+
+          return _buildItem(context, currentItem, index, vm);
+        }): [],
       ),
     );
   }
@@ -60,15 +64,15 @@ class ChooseHouseCleanContent extends HookConsumerWidget {
     final num = HouseCleanItem.num?? 1;
     final price = HouseCleanItem.price?? 0;
 
-    Log.d("6666  ${HouseCleanItem.isDisable}");
-    bool isChecked = HouseCleanItem.isChecked??false;
 
+    bool isChecked = HouseCleanItem.isChecked??false;
     bool disabled = HouseCleanItem.isDisable??false;
     if(useScence !=null){
       disabled = true;
     }else {
       disabled = false;
     }
+    final isCheckedState = useState<bool>(isChecked);
     final isDisable = useState<bool>(disabled);
 
     return Container(
@@ -116,10 +120,9 @@ class ChooseHouseCleanContent extends HookConsumerWidget {
                 child: MyButton(
                   text: '\$$price',
                   onPressed: (){
-                    Log.d("$isChecked  $isDisable");
                     if(!isDisable.value){
-                      isChecked = !isChecked;
-                      vm.handlerChangeNum(context, isChecked, index);
+                      isCheckedState.value = !isCheckedState.value;
+                      vm.handlerChangeItemChecked(context, isCheckedState.value, index);
                     }
                   },
                   minWidth: 80,
@@ -127,8 +130,8 @@ class ChooseHouseCleanContent extends HookConsumerWidget {
                   fontSize: 19,
                   fontWeight: FontWeight.w500,
                   // enable: !isDisable.value,
-                  textColor:  isChecked? context.appColors.textWhite: context.appColors.textPrimary,
-                  backgroundColor: isChecked? context.appColors.textPrimary:context.appColors.textWhite,
+                  textColor:  isCheckedState.value? context.appColors.textWhite: context.appColors.textPrimary,
+                  backgroundColor: isCheckedState.value ? context.appColors.textPrimary:context.appColors.textWhite,
                   disabledBackgroundColor: context.appColors.disEnableGray,
                   disabledTextColor: context.appColors.textWhite,
                 ),

+ 10 - 7
packages/cpt_services/lib/components/chooseHouseCleanContent_state.dart

@@ -1,18 +1,21 @@
 class ChooseHouseCleanContentState{
-  // 设置一个get  totalPrice
-  // 设置一个get totalPrice
-  get totalPrice => HouseCleanList.map((item) => (item.isChecked ?? false) ? (item.num ?? 1) * (item.price ?? 0) : 0).reduce((before, current) => before + current);
-  List<HouseCleanContentItem> HouseCleanList = [];
+  // totalPrice
+  get totalPrice => houseCleanList?.map((item) => (item.isChecked ?? false) ? (item.num ?? 1) * (item.price ?? 0) : 0).reduce((before, current) => before + current)?? 0;
+  // hasCheckdService
+  get hasCheckdService => houseCleanList?.any((item) => (item.isChecked ?? false)) ?? false;
+  // 选取的服务项目
+  get checkedServiceList => houseCleanList?.where((item) => (item.isChecked ?? false))?.toList() ?? [];
+  List<HouseCleanContentItem>? houseCleanList;
 
   ChooseHouseCleanContentState({
-    required this.HouseCleanList,
+    required this.houseCleanList,
   });
 
   ChooseHouseCleanContentState copyWith({
-    List<HouseCleanContentItem>? HouseCleanList,
+    List<HouseCleanContentItem>? houseCleanList,
   }){
     return ChooseHouseCleanContentState(
-      HouseCleanList: HouseCleanList??this.HouseCleanList,
+      houseCleanList: houseCleanList??this.houseCleanList,
     );
   }
 }

+ 59 - 66
packages/cpt_services/lib/components/chooseHouseCleanContent_vm.dart

@@ -1,4 +1,5 @@
 
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -13,73 +14,39 @@ import 'chooseHouseCleanContent_state.dart';
 part 'chooseHouseCleanContent_vm.g.dart';
 
 
-List<Map<String, dynamic>> HouseCleanList = [
-  {
-    "name": "House Clean 1(unit)",
-    "id": 1,
-    "price": 40.0,
-    "num":1,
-    "areaSizeRange": "≤600 sqft",
-    "isChecked": false,
-    "isDisable": false,
-  },
-  {
-    "name": "House Clean 2(unit)",
-    "id": 2,
-    "price": 57.0,
-    "num":1,
-    "areaSizeRange": "601-800 sqft",
-    "isChecked": false,
-    "isDisable": false,
-  },
-  {
-    "name": "House Clean 3(unit)",
-    "id": 3,
-    "price": 72.0,
-    "num":1,
-    "areaSizeRange": "801-1000 sqft",
-    "isChecked": false,
-    "isDisable": false,
-  },
-  {
-    "name": "House Clean 3(unit)",
-    "id": 4,
-    "price": 85.0,
-    "num":1,
-    "areaSizeRange": "1001-1200 sqft",
-    "isChecked": false,
-    "isDisable": false,
-  },
-];
-
-
-
-
-
 @riverpod
 class ChooseHouseCleanContentVm extends _$ChooseHouseCleanContentVm {
   late ServicesRespository serviceRespositoryInstance;
 
-  late BuildContext _context;
-  late Map<String, dynamic>? _initProps;
+
+  List<PaidServiceDetailProducts> _products = [];
+
+  List<Map<String, dynamic>> houseCleanList = [];
+
 
   ChooseHouseCleanContentState initState(){
     Log.d("--------------------------initState---------------------");
-    List<HouseCleanContentItem> HouseCleanListNew = [];
-    HouseCleanList.forEach((item) {
-      HouseCleanContentItem newItem = HouseCleanContentItem()
-        ..id = item['id']
-        ..price = item['price'] as double
-        ..name = item['name']
-        ..num = 1
-        ..areaSizeRange = item['areaSizeRange']
-        ..isChecked = item['isChecked']
-        ..isDisable = item['isDisable'];
-        HouseCleanListNew.add(newItem);
-    });
-    return ChooseHouseCleanContentState(
-      HouseCleanList: HouseCleanListNew,
-    );
+    if(houseCleanList.isNotEmpty){
+      List<HouseCleanContentItem> houseCleanListNew = [];
+      houseCleanList.forEach((item) {
+        HouseCleanContentItem newItem = HouseCleanContentItem()
+          ..id = item['id']
+          ..price = item['price'] as double
+          ..name = item['name']
+          ..num = 1
+          ..areaSizeRange = item['areaSizeRange']
+          ..isChecked = item['isChecked']
+          ..isDisable = item['isDisable'];
+        houseCleanListNew.add(newItem);
+      });
+      return ChooseHouseCleanContentState(
+        houseCleanList: houseCleanListNew,
+      );
+    }else {
+      return ChooseHouseCleanContentState(
+        houseCleanList: null,
+      );
+    }
   }
 
   @override
@@ -92,16 +59,42 @@ class ChooseHouseCleanContentVm extends _$ChooseHouseCleanContentVm {
   }
 
   setInitPageData(BuildContext context, Map<String, dynamic>? params){
-    _context = context;
     Log.d("--------------------------setInitPageData----------$params-----------");
-    _initProps = params;
-
+    _products = params?['products']??[];
+
+    // 渲染一帧后
+    WidgetsBinding.instance.addPostFrameCallback((_){
+      // 修改 state 中 HouseCleanList
+      if(_products != null){
+        if(_products != null && _products.isNotEmpty){
+          List<PaidServiceDetailProducts> products = _products;
+          List<HouseCleanContentItem> houseCleanListNew = [];
+          products.forEach((item) {
+            HouseCleanContentItem newItem = HouseCleanContentItem()
+              ..id = item.id
+              ..price = (item.price ?? 0.0).toDouble()
+              ..name = item.name
+              ..num = 1
+              ..areaSizeRange = item.shortDescription
+              ..isChecked = false
+              ..isDisable = false;
+            houseCleanListNew.add(newItem);
+          });
+
+          state = state.copyWith(
+            houseCleanList: houseCleanListNew,
+          );
+        }
+      }
+    });
   }
 
-  handlerChangeNum(BuildContext context, bool isChecked, int index){
-    state.HouseCleanList[index].isChecked = isChecked;
+  // 修改 item 的选中状态
+  handlerChangeItemChecked(BuildContext context, bool isChecked, int index){
+    List<HouseCleanContentItem> newHouseCleanList = state.houseCleanList!;
+    newHouseCleanList?[index].isChecked = isChecked;
     state = state.copyWith(
-      HouseCleanList: state.HouseCleanList,
+      houseCleanList: newHouseCleanList,
     );
   }
 }

+ 1 - 1
packages/cpt_services/lib/components/chooseHouseCleanContent_vm.g.dart

@@ -7,7 +7,7 @@ part of 'chooseHouseCleanContent_vm.dart';
 // **************************************************************************
 
 String _$chooseHouseCleanContentVmHash() =>
-    r'2f810b6f7f58c4f52a4f0c97e23d837511d3d3e7';
+    r'acb10c35766b4580f8f01dd53555e24817941f1e';
 
 /// See also [ChooseHouseCleanContentVm].
 @ProviderFor(ChooseHouseCleanContentVm)

+ 8 - 4
packages/cpt_services/lib/components/chooseHouseCleanTitle.dart

@@ -1,6 +1,9 @@
 
 import 'package:cpt_services/components/chooseHouseCleanContent_vm.dart';
+import 'package:cpt_services/components/chooseVisitTimeContent_vm.dart';
+import 'package:cpt_services/components/chooseVisitTimeTitle_vm.dart';
 import 'package:cpt_services/modules/services/service_clean_detail/service_clean_detail_vm.dart';
+import 'package:cpt_services/modules/services/service_order_confirm/service_order_confirm_vm.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
@@ -15,18 +18,19 @@ import 'package:widgets/widget_export.dart';
 
 class ChooseHouseCleanTitle extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   const ChooseHouseCleanTitle(
-      {Key? key,required this.id, required this.serviceTypeCode,}) : super(key: key);
+      {Key? key,required this.id, required this.cleanServiceType,}) : super(key: key);
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final totalPrice = ref.watch(chooseHouseCleanContentVmProvider.select((state)=>state.totalPrice));
+    final totalPrice = ref.watch(serviceOrderConfirmVmProvider.select((state)=>state.totalPrice));
 
+    final vm = ref.read(chooseVisitTimeContentVmProvider.notifier);
     useEffect((){
       // 组件挂载时执行 - 执行接口请求
-      // Future.microtask(() => vm.initPageData());
+      Future.microtask(() => vm.initPageData(context));
       return () {
         // 组件卸载时执行
       };

+ 7 - 5
packages/cpt_services/lib/components/chooseVisitTimeBottomFooter.dart

@@ -13,18 +13,20 @@ import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 import 'package:widgets/my_cart_num.dart';
 
+import '../modules/services/service_order_confirm/service_order_confirm_vm.dart';
+
 class ChooseVisitTimeBottomFooter extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
-  const ChooseVisitTimeBottomFooter({Key? key,required this.id, required this.serviceTypeCode}) : super(key: key);
+  const ChooseVisitTimeBottomFooter({Key? key,required this.id, required this.cleanServiceType}) : super(key: key);
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(chooseVisitTimeBottomFooterVmProvider.notifier);
     final state = ref.watch(chooseVisitTimeBottomFooterVmProvider);
 
-    final totalPrice = ref.watch(chooseVisitTimeContentVmProvider.select((state) => state.totalPrice));
+    double toTalPrice = ref.watch(serviceOrderConfirmVmProvider.select((state) => state.totalPrice??0.0));
 
     useEffect((){
       // 组件挂载时执行 - 执行接口请求
@@ -58,7 +60,7 @@ class ChooseVisitTimeBottomFooter extends HookConsumerWidget {
                     mainAxisSize: MainAxisSize.max,
                     children: [
                       MyTextView(
-                        "\$$totalPrice",
+                        "\$$toTalPrice",
                         fontSize: 18,
                         textColor: Colors.white,
                         isFontRegular: true,
@@ -86,7 +88,7 @@ class ChooseVisitTimeBottomFooter extends HookConsumerWidget {
                 ),
               ),
             ).onTap((){
-              vm.handlerClickVisitTimeConfirm(context, id: id , serviceTypeCode: serviceTypeCode);
+              vm.handlerClickVisitTimeConfirm(context, id: id , cleanServiceType: cleanServiceType);
             }),
           ),
         ],

+ 22 - 4
packages/cpt_services/lib/components/chooseVisitTimeBottomFooter_vm.dart

@@ -1,7 +1,9 @@
 
+import 'package:cpt_services/components/chooseVisitTimeTitle_vm.dart';
 import 'package:cpt_services/modules/services/service_order_confirm/service_order_confirm_vm.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -9,6 +11,7 @@ import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/dialog/dialog_content_wrap.dart';
 
 import '../../../respository/services_respository.dart';
+import 'chooseVisitTimeContent_vm.dart';
 
 part 'chooseVisitTimeBottomFooter_vm.g.dart';
 
@@ -62,10 +65,25 @@ class ChooseVisitTimeBottomFooterVm extends _$ChooseVisitTimeBottomFooterVm {
     // );
   }
 
-  handlerClickVisitTimeConfirm(BuildContext context,{required int id, required int serviceTypeCode} ){
+  // 预约时间点击了confirm
+  handlerClickVisitTimeConfirm(BuildContext context,{required int id, required String cleanServiceType} ){
     Log.d("handlerClickVisitTimeConfirm");
-    // 关闭 visitTime 弹框
-    final serviceOrderConfrimVm = ref.read(serviceOrderConfirmVmProvider.notifier);
-    serviceOrderConfrimVm.handlerHideVisitTimeDialog();
+    final visitTimeContentVm = ref.read(chooseVisitTimeContentVmProvider.notifier);
+    if(visitTimeContentVm.state.allSelectedTimeList !=null && visitTimeContentVm.state.allSelectedTimeList!.isNotEmpty ){
+      // 有选中的时间
+      // 关闭 visitTime 弹框
+      // 需要更新 confirmOrdervm 的 visitTime
+      final serviceOrderConfrimVm = ref.read(serviceOrderConfirmVmProvider.notifier);
+      final visitTimeTitleVm = ref.read(chooseVisitTimeTitleVmProvider.notifier);
+      final visitTimeContentVm = ref.read(chooseVisitTimeContentVmProvider.notifier);
+
+      // String visitTime = visitTimeTitleVm.state.currentSelectDayInfoItem.date! + ' ' + visitTimeContentVm.state.allSelectedTimeList!.first?.time!;
+      String visitTime = visitTimeContentVm.state.allSelectedTimeList!.first?.time!??'';
+      serviceOrderConfrimVm.handlerHideVisitTimeDialog();
+      serviceOrderConfrimVm.handlerUpdateVisitTime(visitTime);
+    }else {
+      // 没有选中预约时间
+      ToastEngine.show("Please Choose Visit Time");
+    }
   }
 }

+ 1 - 1
packages/cpt_services/lib/components/chooseVisitTimeBottomFooter_vm.g.dart

@@ -7,7 +7,7 @@ part of 'chooseVisitTimeBottomFooter_vm.dart';
 // **************************************************************************
 
 String _$chooseVisitTimeBottomFooterVmHash() =>
-    r'7ef89e7901bf6761ee066d4ef93bbdf7a6ce59c5';
+    r'5139b3c161e0f751a573fd4e13afb81be48557b2';
 
 /// See also [ChooseVisitTimeBottomFooterVm].
 @ProviderFor(ChooseVisitTimeBottomFooterVm)

+ 61 - 30
packages/cpt_services/lib/components/chooseVisitTimeContent.dart

@@ -4,6 +4,7 @@ import 'package:cpt_services/components/chooseVisitTimeBottomFooter.dart';
 import 'package:cpt_services/components/chooseVisitTimeBottomFooter_vm.dart';
 import 'package:cpt_services/components/chooseVisitTimeContent_vm.dart';
 import 'package:cpt_services/components/status_card_item.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';
@@ -15,6 +16,7 @@ import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 import 'package:widgets/my_cart_num.dart';
@@ -25,7 +27,7 @@ import 'chooseVisitTimeContent_state.dart';
 
 class ChooseVisitTimeContent extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
   final double contentTopSectionHeight;
   final double contentMaxHeight;
   final double bottomBtnSectionHeight;
@@ -33,7 +35,7 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
   const ChooseVisitTimeContent({
     Key? key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
     this.contentTopSectionHeight = 150,
     this.contentMaxHeight = 480,
     this.bottomBtnSectionHeight = 50,
@@ -45,6 +47,7 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
     final state = ref.watch(chooseVisitTimeContentVmProvider);
 
     useEffect((){
+      vm.setInitPageData(context, id, cleanServiceType);
       // 组件挂载时执行 - 执行接口请求
       Future.microtask(() => vm.initPageData(context));
       return () {
@@ -58,7 +61,7 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
         // final minHeight = constraints.minHeight;
         // final maxWidth = constraints.maxWidth;
         // Log.d("---maxHeight-----$maxHeight-- $minHeight  $maxWidth--");
-        double scrollMaxHeight = contentMaxHeight - contentTopSectionHeight - bottomBtnSectionHeight ;
+        // double scrollMaxHeight = contentMaxHeight - contentTopSectionHeight - bottomBtnSectionHeight ;
         // Log.d("scrollMaxHeight  $scrollMaxHeight");
         return Container(
           width: double.infinity,
@@ -71,7 +74,7 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
           ),
           child: LoadStateLayout(
             state: state.loadingState,
-            successSliverWidget: [
+            successSliverWidget: state.visitTimeList!=null && state.visitTimeList.isNotEmpty?[
               SliverGrid(
                 gridDelegate:  const SliverGridDelegateWithFixedCrossAxisCount(
                 crossAxisCount: 4,
@@ -87,21 +90,19 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
                   },
                   childCount: state.visitTimeList.length,
                 ),
-
-                // GridView.builder(
-                //   gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
-                //     crossAxisCount: 4,
-                //     mainAxisSpacing: 5,
-                //     crossAxisSpacing: 5,
-                //     childAspectRatio: 80 / 38,
-                //   ),
-                //   itemCount: state.visitTimeList.length,
-                //   itemBuilder: (context, index) {
-                //     final item = state.visitTimeList[index];
-                //     return _buildTimeItem(context, index, item, ref, vm);
-                //   },
-                // )
               )
+            ]: [
+              SliverList( delegate: SliverChildBuilderDelegate(
+                      (context, index){
+                    return  const Center(
+                        child: SizedBox(
+                          height: 250,
+                          child: MyAssetImage(Assets.baseServicePageNoData, width: 123.5, height: 115.5, fit: BoxFit.contain),
+                        ),
+                      );
+                  },
+                  childCount: 1
+              ),)
             ],
           ),
         );
@@ -111,17 +112,27 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
 
 
   Widget _buildTimeItem(BuildContext context,int index, VisitTimeContentItem item, WidgetRef ref, vm){
-    final name = item.name;
+    final state = ref.watch(chooseVisitTimeContentVmProvider);
+
+    final itemIsChecked = ref.watch(chooseVisitTimeContentVmProvider.select((state) =>
+       state.visitTimeList[index].isChecked ?? false
+    ));
+    final timeText = item.timeText;
     return HookBuilder(
       builder: (context) {
-        final isChecked = useState<bool>(item.isChecked??false);
+        final isMultiSelect = useState<bool>(state.isMultiSelect??false);
+        // final isChecked = useState<bool>(itemIsChecked??false);
+        final enable = useState<bool>(item.enable??false);
+        final urgent = useState<bool>(item.urgent??false); // 是否加急
+        final holiday = useState<bool>(item.holiday??false); // 是否节假日
+        final night = useState<bool>(item.night??false); // 是否晚上
         return SizedBox(
           width: 80,
           child: Stack(
             children: [
               Container(
                 decoration: BoxDecoration(
-                  color: isChecked.value? ColorUtils.string2Color("#D9DFF6"):context.appColors.whiteBG,
+                  color: itemIsChecked? ColorUtils.string2Color("#D9DFF6"):context.appColors.whiteBG,
                   borderRadius: BorderRadius.circular(8),
                   boxShadow: [
                     BoxShadow(
@@ -133,18 +144,23 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
                 ),
                 child:  MyButton(
                   onPressed: (){
-                    isChecked.value = !isChecked.value;
-                    vm.handlerTimeItemClick(context, index, isChecked.value);
+                    if(enable.value){
+                      // 可选  - 点击时间
+                      vm.handlerTimeItemClick(context, index,!itemIsChecked);
+                    }
                   },
-                  text: '$name',
-                  minHeight: 38,
-                  textColor: isChecked.value?context.appColors.textPrimary: context.appColors.textDarkGray999,
+                  text: '$timeText',
+                  textColor: itemIsChecked ?context.appColors.textPrimary: context.appColors.textDarkGray999,
+                  enable: enable.value,
+                  disabledBackgroundColor: context.appColors.disEnableGray,
+                  disabledTextColor: context.appColors.textWhite,
                   fontSize: 12,
                   fontWeight: FontWeight.w400,
                 )
               ),
+              // 加急
               Positioned(
-                child: MyTextView(
+                child: urgent.value? MyTextView(
                   'Extreme speed',
                   textColor: ColorUtils.string2Color("#DD6800"),
                   fontSize: 8,
@@ -157,10 +173,25 @@ class ChooseVisitTimeContent extends HookConsumerWidget {
                 ).clipRRect(
                   topLeft: 10,
                   bottomRight: 10
-                ).onTap((){
-
-                }),
+                ): const SizedBox.shrink(),
               ),
+              // 节假日
+              // Positioned(
+              //   child: urgent.value? MyTextView(
+              //     'Extreme speed',
+              //     textColor: ColorUtils.string2Color("#DD6800"),
+              //     fontSize: 8,
+              //     isFontRegular: true,
+              //     backgroundColor:ColorUtils.string2Color("#FFEBD9"),
+              //     paddingTop: 2,
+              //     paddingBottom: 2,
+              //     paddingLeft: 5,
+              //     paddingRight: 5,
+              //   ).clipRRect(
+              //       topLeft: 10,
+              //       bottomRight: 10
+              //   ): const SizedBox.shrink(),
+              // ),
             ],
           ),
         );

+ 41 - 22
packages/cpt_services/lib/components/chooseVisitTimeContent_state.dart

@@ -1,67 +1,86 @@
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:widgets/load_state_layout.dart';
 
 import 'visitTimeType.dart';
 
 class ChooseVisitTimeContentState{
-  // 设置一个get  totalPrice
-  get totalPrice => visitTimeList.map((item) => (item.isChecked??false) ? item.price??0 : 0 ).reduce((before, current) => before + current);
+  // 当前所选中的所有时间段集合
+  List<VisitTimeContentItem> get allSelectedTimeList => visitTimeList.where((item) => item.isChecked??false).toList();
 
   //页面 LoadView 状态的展示
   LoadState loadingState;
   String? errorMessage;
 
+  // 是否可多选
+  bool? isMultiSelect;
   List<VisitTimeContentItem> visitTimeList = [];
+  String currentDate = DateTimeUtils.formatDate(DateTime.now(), format: "yyyy-MM-dd");
+
 
   ChooseVisitTimeContentState({
     this.loadingState = LoadState.State_Loading,
     this.errorMessage,
-    required this.visitTimeList,
-  });
+    this.isMultiSelect = false,
+    required this.currentDate,
+    List<VisitTimeContentItem>? visitTimeList,
+  }) {
+    this.visitTimeList = visitTimeList ?? [];
+  }
 
   ChooseVisitTimeContentState copyWith({
     LoadState? loadingState,
     String? errorMessage,
+    bool? isMultiSelect,
     List<VisitTimeContentItem>? visitTimeList,
-  }){
+    String? currentDate,
+  }) {
     return ChooseVisitTimeContentState(
-      loadingState: loadingState??this.loadingState,
-      errorMessage: errorMessage??this.errorMessage,
-      visitTimeList: visitTimeList??this.visitTimeList,
+      loadingState: loadingState ?? this.loadingState,
+      errorMessage: errorMessage ?? this.errorMessage,
+      isMultiSelect: isMultiSelect ?? this.isMultiSelect,
+      visitTimeList: visitTimeList ?? this.visitTimeList,
+      currentDate: currentDate ?? this.currentDate,
     );
   }
 }
 
+
 class VisitTimeContentItem{
-  String? name;
   int? id;
-  double? price;
-  Map<String, dynamic>? type;
+  String? timeText;
+  String? time;
+  bool? urgent;
+  bool? holiday;
+  bool? night;
   bool? isChecked;
-  bool? isDisable;
+  bool? enable;
   VisitTimeContentItem({
-    this.name,
     this.id,
-    this.price,
-    this.type,
+    this.timeText,
+    this.time,
+    this.urgent,
+    this.holiday,
+    this.night,
     this.isChecked = false,
-    this.isDisable = false,
+    this.enable = false,
   });
 
   VisitTimeContentItem copyWith({
     String? name,
     int? id,
-    double? price,
     Map<String, dynamic>? type,
     bool? isChecked,
-    bool? isDisable,
+    bool? enable,
   }){
     return VisitTimeContentItem(
-        name: name??this.name,
         id: id??this.id,
-        price: price??this.price,
-        type: type ?? this.type, // 在这里设置默认值
+        timeText: timeText??this.timeText,
+        time: time??this.time,
+        urgent: urgent??this.urgent,
+        holiday: holiday??this.holiday,
+        night: night??this.night,
         isChecked: isChecked??this.isChecked,
-        isDisable: isDisable??this.isDisable,
+        enable: enable??this.enable,
     );
   }
 }

+ 97 - 241
packages/cpt_services/lib/components/chooseVisitTimeContent_vm.dart

@@ -1,9 +1,12 @@
 
 import 'package:cpt_services/modules/services/service_order_confirm/service_order_confirm_vm.dart';
+import 'package:domain/entity/service_time_period_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 
 import 'package:widgets/dialog/dialog_content_wrap.dart';
@@ -16,143 +19,45 @@ part 'chooseVisitTimeContent_vm.g.dart';
 
 
 List<Map<String, dynamic>> visitTimeList = [
-  {
-    "name": "08:00 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "08:30 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "09:00 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "09:30 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "10:00 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "10:30 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "11:00 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "11:30 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "12:00 AM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "12:30 PM",
-    "id": 1,
-    "price": 40.0,
-    "type": null
-  },
-  {
-    "name": "13:00 PM",
-    "id": 1,
-    "price": 50.0,
-    "type": {
-      "text": "Extreme speed",
-      "type": "extremeSpeed",
-      'code': 1,
-    }
-  },
-  {
-    "name": "13:30 PM",
-    "id": 1,
-    "price": 50.0,
-    "type": {
-      "text": "Extreme speed",
-      "type": "extremeSpeed",
-      'code': 1,
-    }
-  },
-  {
-    "name": "14:00 PM",
-    "id": 1,
-    "price": 50.0,
-    "type": {
-      "text": "Extreme speed",
-      "type": "extremeSpeed",
-      'code': 1,
-    }
-  },
-  {
-    "name": "14:30 PM",
-    "id": 1,
-    "price": 50.0,
-    "type": {
-      "text": "Extreme speed",
-      "type": "extremeSpeed",
-      'code': 1,
-    }
-  },
-  {
-    "name": "15:00 PM",
-    "id": 1,
-    "price": 50.0,
-    "type": {
-      "text": "Extreme speed",
-      "type": "extremeSpeed",
-      'code': 1,
-    }
-  },
+  // {
+  //   "time_text": "07:00 AM",
+  //   "time": "2025-01-16 07:00:00",
+  //   "urgent": false,
+  //   "holiday": false,
+  //   "night": false,
+  //   "enable": false
+  // },
 ];
 
 
 
-
-
-
 @riverpod
 class ChooseVisitTimeContentVm extends _$ChooseVisitTimeContentVm {
   late ServicesRespository serviceRespositoryInstance;
 
+  late BuildContext _context;
+  late int _id;
+  late String _cleanServiceType;
+
   ChooseVisitTimeContentState initState(){
     Log.d("--------------------------initState---------------------");
     List<VisitTimeContentItem> visitTimeListNew = [];
     visitTimeList.forEach((item) {
       VisitTimeContentItem newItem = VisitTimeContentItem()
-        ..id = item['id']
-        ..price = item['price'] as double
-        ..name = item['name']
-        ..type = null
-        ..isDisable = false
+        ..id = null
+        ..urgent = item['urgent']
+        ..holiday = item['holiday']
+        ..night = item['night']
+        ..time = item['time']
+        ..timeText = item['time_text']
+        ..enable = item['enable']
         ..isChecked = false;
       visitTimeListNew.add(newItem);
     });
 
     return ChooseVisitTimeContentState(
       visitTimeList: visitTimeListNew,
+      currentDate: DateTimeUtils.formatDate(DateTime.now(), format: "yyyy-MM-dd"),
     );
   }
 
@@ -160,9 +65,7 @@ class ChooseVisitTimeContentVm extends _$ChooseVisitTimeContentVm {
   ChooseVisitTimeContentState build(){
     // 引入数据仓库
     serviceRespositoryInstance = ref.read(servicesRespositoryProvider);
-     state = initState();
-    Log.d("--------------------------build---------------------");
-
+    state = initState();
     return state;
   }
 
@@ -171,134 +74,72 @@ class ChooseVisitTimeContentVm extends _$ChooseVisitTimeContentVm {
         loadingState: loadState,
         errorMessage: errorMsg
     );
+    // Log.d("87338  ${state.currentDate}");
+    Log.d("87338  ${state.visitTimeList}");
+  }
+
+  setInitPageData(BuildContext context, int id, String cleanServiceType){
+    _context = context;
+    _id = id;
+    _cleanServiceType = cleanServiceType;
   }
 
   initPageData(BuildContext context){
-    changeLoadingState(LoadState.State_Success, null);
+    // changeLoadingState(LoadState.State_Success, null);
+    getVisitTimeList(context, DateTimeUtils.formatDate(DateTime.now(), format: "yyyy-MM-dd"));
   }
 
-  Future<ChooseVisitTimeContentState> getVisitTimeList(BuildContext context) async{
+  // 获取指定 日期下面的所有 时间段
+  Future getVisitTimeList(BuildContext context, String date) async{
     Log.d("--------------------------getVisitTimeList---------------------");
     // 获取数据
-    // state.visitTimeList = serviceRespositoryInstance.getVisitTimeList();
-    // state = state.copyWith(
-    //   visitTimeList: state.visitTimeList,
-    // );
-
     changeLoadingState(LoadState.State_Loading, null);
+    try {
+      //请求网络
+      Map<String, dynamic>  params = {
+        "id": _id,
+        "date": date,
+      };
+      Log.d("请求参数------$params");
+      final result = await serviceRespositoryInstance.fetchPaidServiceTimePeriod(params);
+      //校验成功失败
+      if (result.isSuccess) {
+        List<ServiceTimePeriodEntity>? resultEntityList = result.list as List<ServiceTimePeriodEntity>;
+        handlerResultList(resultEntityList);
+      } else {
+        String errorMessage = result.errorMsg!;
+        changeLoadingState(LoadState.State_Error, errorMessage);
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
 
-    List<Map<String, dynamic>> visitTimeList = [
-      {
-        "name": "10:00 AM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "10:30 AM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "11:00 AM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "11:30 AM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "12:00 AM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "12:30 PM",
-        "id": 1,
-        "price": 40.0,
-        "type": null
-      },
-      {
-        "name": "13:00 PM",
-        "id": 1,
-        "price": 50.0,
-        "type": {
-          "text": "Extreme speed",
-          "type": "extremeSpeed",
-          'code': 1,
-        }
-      },
-      {
-        "name": "13:30 PM",
-        "id": 1,
-        "price": 50.0,
-        "type": {
-          "text": "Extreme speed",
-          "type": "extremeSpeed",
-          'code': 1,
-        }
-      },
-      {
-        "name": "14:00 PM",
-        "id": 1,
-        "price": 50.0,
-        "type": {
-          "text": "Extreme speed",
-          "type": "extremeSpeed",
-          'code': 1,
-        }
-      },
-      {
-        "name": "14:30 PM",
-        "id": 1,
-        "price": 50.0,
-        "type": {
-          "text": "Extreme speed",
-          "type": "extremeSpeed",
-          'code': 1,
-        }
-      },
-      {
-        "name": "15:00 PM",
-        "id": 1,
-        "price": 50.0,
-        "type": {
-          "text": "Extreme speed",
-          "type": "extremeSpeed",
-          'code': 1,
-        }
-      },
-    ];
-    await Future.delayed(Duration(seconds: 1), (){});
-
-    List<VisitTimeContentItem> visitTimeListNew = [];
-    visitTimeList.forEach((item) {
-      VisitTimeContentItem newItem = VisitTimeContentItem()
-        ..id = item['id']
-        ..price = item['price'] as double
-        ..name = item['name']
-        ..type = null
-        ..isDisable = false
-        ..isChecked = false;
-      visitTimeListNew.add(newItem);
-    });
-
-    state = state.copyWith(
-      visitTimeList: visitTimeListNew,
-    );
-    Log.d("--------------------------getVisitTimeList END   ${state.visitTimeList}---------------------");
+  }
 
-    changeLoadingState(LoadState.State_Success, null);
 
-    return ChooseVisitTimeContentState(
-      visitTimeList: visitTimeListNew,
-    );
+  void handlerResultList(List<ServiceTimePeriodEntity>? list) {
+    if(list != null && list.isNotEmpty){
+      // 需要模型转换 将 ServiceTimePeriodEntity 转换为 VisitTimeContentItem
+      List<VisitTimeContentItem> newList = [];
+      list.asMap().forEach((index,item) {
+        VisitTimeContentItem newVisitTimeContentItem = VisitTimeContentItem()
+          ..id = index
+          ..urgent = item.urgent
+          ..holiday = item.holiday
+          ..night = item.night
+          ..time = item.time
+          ..timeText = item.timeText
+          ..enable = item.enable
+          ..isChecked = false;
+        newList.add(newVisitTimeContentItem);
+      });
+
+      state.visitTimeList!.clear();
+      state.visitTimeList!.addAll(newList);
+      //更新展示的状态
+      changeLoadingState(LoadState.State_Success, null);
+    }
   }
 
 
@@ -309,13 +150,28 @@ class ChooseVisitTimeContentVm extends _$ChooseVisitTimeContentVm {
     // );
   }
 
-  handlerTimeItemClick(BuildContext context, int index, bool isSelected){
+  // 点击 时间段
+  handlerTimeItemClick(BuildContext context, int index, bool changetoValue){
+    Log.d("index:${index} 的 isChecked属性  变换成: $changetoValue");
     // 修改 状态
-    state.visitTimeList[index].isChecked = isSelected;
+    if(state.isMultiSelect??false){
+      // 可多选
+      state.visitTimeList[index].isChecked = changetoValue;
+    }else {
+      // 不可多选
+      state.visitTimeList.asMap().forEach((i,item) {
+        if(i == index){
+          item.isChecked = changetoValue;
+        }else {
+          item.isChecked = false;
+        }
+      });
+    }
     state = state.copyWith(
       visitTimeList: state.visitTimeList,
     );
 
-    ref.read(serviceOrderConfirmVmProvider.notifier).setConfirmOrderTotalPrice(context);
+    final serviceOrderConfirmVm = ref.read(serviceOrderConfirmVmProvider.notifier);
+    serviceOrderConfirmVm?.setConfirmOrderTotalPrice(context);
   }
 }

+ 1 - 1
packages/cpt_services/lib/components/chooseVisitTimeContent_vm.g.dart

@@ -7,7 +7,7 @@ part of 'chooseVisitTimeContent_vm.dart';
 // **************************************************************************
 
 String _$chooseVisitTimeContentVmHash() =>
-    r'f7465ee5636aac140e046ba07c02e64117890fe4';
+    r'354e573081792050eac7d9ec5dccf496e9d2bf66';
 
 /// See also [ChooseVisitTimeContentVm].
 @ProviderFor(ChooseVisitTimeContentVm)

+ 2 - 11
packages/cpt_services/lib/components/chooseVisitTimeTitle.dart

@@ -18,10 +18,10 @@ import 'chooseVisitTimeTitle_vm.dart';
 
 class ChooseVisitTimeTitle extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   const ChooseVisitTimeTitle(
-      {Key? key,required this.id, required this.serviceTypeCode,}) : super(key: key);
+      {Key? key,required this.id, required this.cleanServiceType,}) : super(key: key);
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
@@ -54,15 +54,6 @@ class ChooseVisitTimeTitle extends HookConsumerWidget {
                   boxWidth: double.infinity,
                   // maxLines: 5,
                 ),
-                MyTextView(
-                  '30 minutes before the start of the service, free time modification is available',
-                  textColor: context.appColors.textDarkGray999,
-                  textAlign: TextAlign.left,
-                  isFontRegular: true,
-                  fontSize: 14,
-                  // maxLines: 5,
-                  boxWidth: double.infinity,
-                ),
               ],
             ),
           ),

+ 13 - 8
packages/cpt_services/lib/components/chooseVisitTimeTitle_state.dart

@@ -1,18 +1,19 @@
 class ChooseVisitTimeTitleState {
   int? currentSelectIndex;
+  get currentSelectDayInfoItem => dayInfoList![currentSelectIndex!];
   List<DayInfoItem>? dayInfoList;
 
   ChooseVisitTimeTitleState({
     this.currentSelectIndex = 0,
     dayInfoList,
   }): dayInfoList = dayInfoList ?? [
-    DayInfoItem(day: 'Tody', date: '2022-01-01', isSelected: true, isIntrady: true,),
-    DayInfoItem(day: 'Tomorrow', date: '2022-01-02', isSelected: false, isIntrady: false,),
-    DayInfoItem(day: 'Wendnesday', date: '2022-01-03', isSelected: false, isIntrady: false,),
-    DayInfoItem(day: 'Thursdy', date: '2022-01-04', isSelected: false, isIntrady: false,),
-    DayInfoItem(day: 'Friday', date: '2022-01-05', isSelected: false, isIntrady: false,),
-    DayInfoItem(day: 'Saturday', date: '2022-01-06', isSelected: false, isIntrady: false,),
-    DayInfoItem(day: 'Sunday', date: '2022-01-07', isSelected: false, isIntrady: false,),
+    DayInfoItem(day: 'Tody', date: '2022-01-01', isSelected: true, isIntrady: true, holiday:false, enable: true),
+    DayInfoItem(day: 'Tomorrow', date: '2022-01-02', isSelected: false, isIntrady: false,holiday:false, enable: true),
+    DayInfoItem(day: 'Wendnesday', date: '2022-01-03', isSelected: false, isIntrady: false,holiday:false, enable: true),
+    DayInfoItem(day: 'Thursdy', date: '2022-01-04', isSelected: false, isIntrady: false,holiday:false, enable: true),
+    DayInfoItem(day: 'Friday', date: '2022-01-05', isSelected: false, isIntrady: false,holiday:false, enable: true),
+    DayInfoItem(day: 'Saturday', date: '2022-01-06', isSelected: false, isIntrady: false,holiday:false, enable: true),
+    DayInfoItem(day: 'Sunday', date: '2022-01-07', isSelected: false, isIntrady: false,holiday:false, enable: true),
   ];
 
   ChooseVisitTimeTitleState copyWith({
@@ -32,13 +33,17 @@ class DayInfoItem {
   String? day;
   String? date;
   bool isSelected;
-  bool isIntrady;
+  bool? isIntrady;
+  bool? holiday;
+  bool? enable;
   DayInfoItem({
     this.id = 0,
     this.day,
     this.date,
     this.isSelected = false,
     this.isIntrady = false,
+    this.holiday = false,
+    this.enable = true,
   });
 }
 

+ 41 - 18
packages/cpt_services/lib/components/chooseVisitTimeTitle_vm.dart

@@ -5,6 +5,7 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/log_utils.dart';
 
 import 'package:widgets/dialog/dialog_content_wrap.dart';
@@ -70,27 +71,49 @@ List<Map<String, dynamic>> dayInfoList = [
 
 
 
-ChooseVisitTimeTitleState initState(){
-  Log.d("--------------------------initState---------------------");
-  List<DayInfoItem> dayInfoListNew = [];
-  dayInfoList.forEach((item) {
-    DayInfoItem newItem = DayInfoItem()
-      ..id = item['id']
-      ..day = item['day']
-      ..date = item['date']
-      ..isSelected = item['isSelected']
-      ..isIntrady = item['isIntrady'];
-    dayInfoListNew.add(newItem);
-  });
-  return ChooseVisitTimeTitleState(
-    dayInfoList: dayInfoListNew,
-  );
-}
-
 @riverpod
 class ChooseVisitTimeTitleVm extends _$ChooseVisitTimeTitleVm {
   late ServicesRespository serviceRespositoryInstance;
 
+  int _rencentDays = 7;
+
+  formatWeekday(int index, String day){
+    switch (index) {
+      case 0:
+        return 'Today';
+      case 1:
+        return 'Tomorrow';
+      default:
+        return day;
+    }
+  }
+
+  ChooseVisitTimeTitleState initState(){
+    Log.d("--------------------------initState---------------------");
+    List<DayInfoItem> dayInfoListNew = [];
+    // 从当前天开始 生成一份最近一个星期的 DayInfoItem
+    DateTime now = DateTime.now();
+    for(int i = 0; i < _rencentDays; i++){
+      DateTime date = now.add(Duration(days: i));
+      String day = DateTimeUtils.getWeekday(date, languageCode: 'en');
+      String dateStr = date.toString().substring(0, 10);
+      DayInfoItem newItem = DayInfoItem()
+        ..id = i
+        ..day = day = formatWeekday(i, day)
+        ..date = dateStr
+        ..isSelected = i == 0
+        ..isIntrady = i == 0
+        ..holiday = false
+        ..enable = true;
+      dayInfoListNew.add(newItem);
+    }
+
+    return ChooseVisitTimeTitleState(
+      dayInfoList: dayInfoListNew,
+    );
+  }
+
+
   @override
   ChooseVisitTimeTitleState build(){
     // 引入数据仓库
@@ -128,7 +151,7 @@ class ChooseVisitTimeTitleVm extends _$ChooseVisitTimeTitleVm {
 
     // 触发 chooseVisitTimeContent 的刷新
     final chooseVisitTimeContentVm = ref.read(chooseVisitTimeContentVmProvider.notifier);
-    chooseVisitTimeContentVm?.getVisitTimeList(context);
+    chooseVisitTimeContentVm?.getVisitTimeList(context, dayInfoItem.date!);
   }
 
   // 点击某一时间段

+ 1 - 1
packages/cpt_services/lib/components/chooseVisitTimeTitle_vm.g.dart

@@ -7,7 +7,7 @@ part of 'chooseVisitTimeTitle_vm.dart';
 // **************************************************************************
 
 String _$chooseVisitTimeTitleVmHash() =>
-    r'8d58fc35095631b1692ff9a6d2da997b85a4793f';
+    r'23d4d176e8ec0de5f38d7802b1686dc7c77763c6';
 
 /// See also [ChooseVisitTimeTitleVm].
 @ProviderFor(ChooseVisitTimeTitleVm)

+ 3 - 3
packages/cpt_services/lib/components/repair_status_card_item.dart

@@ -16,7 +16,7 @@ import '../constants_services.dart';
 
 class RepairStausCardItem extends HookConsumerWidget {
   int serviceId;
-  int serviceTypeCode;
+  String cleanServiceType;
   int serviceStatusCode;
   Map<String, dynamic> itemObj;
   double? cardHeight ;
@@ -25,7 +25,7 @@ class RepairStausCardItem extends HookConsumerWidget {
   RepairStausCardItem({
     Key? key,
     required this.serviceId,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
     required this.serviceStatusCode,
     required this.itemObj,
     this.onClickCard,
@@ -52,7 +52,7 @@ class RepairStausCardItem extends HookConsumerWidget {
     // Log.d("actionBtnList   $actionBtnList");
 
     useEffect((){
-      vm.setInitData(context, serviceId, serviceTypeCode, serviceStatusCode);
+      vm.setInitData(context, serviceId, cleanServiceType, serviceStatusCode);
       return () {
       };
     },[]);

+ 4 - 4
packages/cpt_services/lib/components/status_card_item_vm.dart

@@ -18,7 +18,7 @@ class StatusCardItemVm extends _$StatusCardItemVm {
   late ServicesRespository serviceRespositoryInstance;
 
   late int _serviceId;
-  late int _serviceTypeCode;
+  late String _cleanServiceType;
   late int _serviceStatusCode;
 
 
@@ -44,9 +44,9 @@ class StatusCardItemVm extends _$StatusCardItemVm {
   //   );
   // }
 
-  setInitData(BuildContext context,int serviceId, int serviceTypeCode, int serviceStatusCode){
+  setInitData(BuildContext context,int serviceId, String cleanServiceType, int serviceStatusCode){
     _serviceId = serviceId;
-    _serviceTypeCode = serviceTypeCode;
+    _cleanServiceType = cleanServiceType;
     _serviceStatusCode = serviceStatusCode;
   }
 
@@ -68,7 +68,7 @@ class StatusCardItemVm extends _$StatusCardItemVm {
       case '4':
         // 去评价
         // context.router.pushNamed('/detail');
-        ServiceEvaluateCreatePage.startInstance(id: _serviceId, serviceTypeCode: _serviceTypeCode,);
+        ServiceEvaluateCreatePage.startInstance(id: _serviceId, cleanServiceType: _cleanServiceType,);
         break;
       default:
         break;

+ 1 - 1
packages/cpt_services/lib/components/status_card_item_vm.g.dart

@@ -6,7 +6,7 @@ part of 'status_card_item_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$statusCardItemVmHash() => r'41c489c1bdf10cb0588de229c4d4bf2b5440d204';
+String _$statusCardItemVmHash() => r'b4fb97b72135c637c44971bb6be4f2adad536023';
 
 /// See also [StatusCardItemVm].
 @ProviderFor(StatusCardItemVm)

+ 10 - 10
packages/cpt_services/lib/constants_services.dart

@@ -1,19 +1,19 @@
 class servicesConstants {
    static Map<String, Map<String, dynamic>> servicesType = {
      "houseCleaning": {
-       "text": "houseCleaning",
-       "type": "houseCleaning",
-       'code': 0,
+       "text": "House Cleaning",
+       "type": "paid",
+       'code': "House Cleaning",  // 业务做 标识 字段
      },
      "airConditioner": {
-       "text": "airConditioner",
-       "type": "airConditioner",
-       'code': 1,
+       "text": "Air Conditioning Cleaning",
+       "type": "paid",
+       'code': "Air Conditioning Cleaning", // 业务做 标识 字段
      },
-     "repaire": {
-       "text": "维修",
-       "type": "repaire",
-       'code': 2,
+     "inquiry": {
+       "text": "Maintenance",
+       "type": "inquiry",
+       'code': "Maintenance",  // 业务做 标识 字段
      }
   };
 

+ 11 - 11
packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_page.dart

@@ -36,22 +36,22 @@ import '../../../components/status_card_item.dart';
 @RoutePage()
 class CleanOrderDetailPage extends HookConsumerWidget {
   final int id; // 订单id
-  final int serviceTypeCode; // 订单类型
+  final String cleanServiceType; // 订单类型
   final int serviesStatusCode; // 订单状态
 
   const CleanOrderDetailPage({
     Key? key,
     @PathParam('id') required this.id,
-    @PathParam('serviceTypeCode') required this.serviceTypeCode,
+    @PathParam('cleanServiceType') required this.cleanServiceType,
     @PathParam('serviesStatusCode') required this.serviesStatusCode,
   }) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required int id, required int serviceTypeCode, required int serviesStatusCode}) {
+  static void startInstance({BuildContext? context, required int id, required String cleanServiceType, required int serviesStatusCode}) {
     if (context != null) {
-      context.router.push(CleanOrderDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode));
+      context.router.push(CleanOrderDetailPageRoute(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode));
     } else {
-      appRouter.push(CleanOrderDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode));
+      appRouter.push(CleanOrderDetailPageRoute(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode));
     }
   }
 
@@ -65,7 +65,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
     Log.d("actionBtnList   $actionBtnList");
 
     useEffect(() {
-      vm.setInitPageData(id: id, serviceTypeCode: serviceTypeCode, serviceStatusCode: serviesStatusCode);
+      vm.setInitPageData(id: id, cleanServiceType: cleanServiceType, serviceStatusCode: serviesStatusCode);
       // 组件挂载时执行 - 执行接口请求
       Future.microtask(() => vm.fetchOrderDetailData(id));
       return () {
@@ -108,7 +108,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                   Visibility(
                     visible: state.loadingState == LoadState.State_Success,
                     child:
-                        state.datas != null ? _buildActionSection(context, state, vm, ref, id, serviceTypeCode, serviesStatusCode, actionBtnList) : Container(),
+                        state.datas != null ? _buildActionSection(context, state, vm, ref, id, cleanServiceType, serviesStatusCode, actionBtnList) : Container(),
                   )
                 ],
               ),
@@ -329,10 +329,10 @@ class CleanOrderDetailPage extends HookConsumerWidget {
           ],
         ),
         
-        // if (serviceTypeCode == servicesConstants.servicesType['houseCleaning']!['code'])
+        // if (cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code'])
         //   // 室内清理
         //   _buildCleanContent(context, state)
-        // else if (serviceTypeCode == servicesConstants.servicesType['airConditioner']!['code'])
+        // else if (cleanServiceType == servicesConstants.servicesType['airConditioner']!['code'])
         //   // 空调清理
         //   _buildCleanContent(context, state)
         // else
@@ -645,7 +645,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
 
   // 底部操作区域
   Widget _buildActionSection(
-      BuildContext context, state, vm, WidgetRef ref, int id, int serviceTypeCode, int serviesStatusCode, List<Map<String, dynamic>> actionBtnList) {
+      BuildContext context, state, vm, WidgetRef ref, int id, String cleanServiceType, int serviesStatusCode, List<Map<String, dynamic>> actionBtnList) {
     return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
       final maxHeight = constraints.maxHeight;
       final minHeight = constraints.minHeight;
@@ -668,7 +668,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
             })),
       ).scrollable(
         scrollDirection: Axis.horizontal,
-        physics: BouncingScrollPhysics(),
+        physics: const BouncingScrollPhysics(),
       );
     });
   }

+ 6 - 6
packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_vm.dart

@@ -47,7 +47,7 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm with DioCancelableMixin {
   bool _needShowPlaceholder = false; //是否展示LoadingView
 
   late int _detailId;
-  late int _detailServiceTypeCode;
+  late String _cleanServiceType;
   late int _detailServiceStatusCode;
 
   // Refresh 控制器
@@ -81,16 +81,16 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm with DioCancelableMixin {
     state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
   }
 
-  setInitPageData({required int id, required int serviceTypeCode, required int serviceStatusCode}) {
+  setInitPageData({required int id, required String cleanServiceType, required int serviceStatusCode}) {
     _detailId = id;
-    _detailServiceTypeCode = serviceTypeCode;
+    _cleanServiceType = cleanServiceType;
     _detailServiceStatusCode = serviceStatusCode;
   }
 
   // 初始化页面数据
-  // initPageData({detailId, detailServiceTypeCode, detailServiceStatusCode}) {
+  // initPageData({detailId, detailcleanServiceType, detailServiceStatusCode}) {
   //   _detailId = detailId??_detailId;
-  //   _detailServiceTypeCode = detailServiceTypeCode??_detailServiceTypeCode;
+  //   _cleanServiceType = detailcleanServiceType??_cleanServiceType;
   //   _detailServiceStatusCode = detailServiceStatusCode??_detailServiceStatusCode;
   //   Log.d("--------------------------initPageData---------------------");
   //   changeLoadingState(LoadState.State_Success, null);
@@ -140,7 +140,7 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm with DioCancelableMixin {
         // Evaluate 去评价
         ServiceEvaluateCreatePage.startInstance(
           id: _detailId,
-          serviceTypeCode: _detailServiceTypeCode,
+          cleanServiceType: _cleanServiceType,
         );
         break;
       default:

+ 1 - 1
packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_vm.g.dart

@@ -7,7 +7,7 @@ part of 'clean_order_detail_vm.dart';
 // **************************************************************************
 
 String _$cleanOrderDetailVmHash() =>
-    r'068199d62a6545c1f8edff8736a13854a79042ab';
+    r'fcfa75c5fcdae98cdcc58d6b872100967a9a3c16';
 
 /// See also [CleanOrderDetailVm].
 @ProviderFor(CleanOrderDetailVm)

+ 5 - 5
packages/cpt_services/lib/modules/services/history/history_page.dart

@@ -45,7 +45,7 @@ class HistoryPage extends HookConsumerWidget {
     final state = ref.watch(historyVmProvider);
     // final appConfigState = ref.watch(appConfigServiceProvider)
 
-    int serviceTypeCode = servicesConstants.servicesType['houseCleaning']?['code'];
+    String cleanServiceType = servicesConstants.servicesType['houseCleaning']?['code'];
     int serviceStatusCode = servicesConstants.servicesStatus['2']?['code'];
 
     useEffect(() {
@@ -95,14 +95,14 @@ class HistoryPage extends HookConsumerWidget {
                         ref,
                         state.list[index],
                         vm,
-                        serviceTypeCode,
+                        cleanServiceType,
                         serviceStatusCode,
                       ).onTap(() {
                         vm.gotoCleanOrderDetailPage(
                           context,
                           state.list[index].id != null ? int.tryParse(state.list[index].id!) ?? 0 : 0,
-                          0,
-                          0,
+                          cleanServiceType,
+                          serviceStatusCode,
                         );
                       });
                     },
@@ -115,7 +115,7 @@ class HistoryPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildHistoryItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, int serviceTypeCode, int serviceStatusCode) {
+  Widget _buildHistoryItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, String cleanServiceType, int serviceStatusCode) {
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,

+ 2 - 2
packages/cpt_services/lib/modules/services/history/history_vm.dart

@@ -197,7 +197,7 @@ class HistoryVm extends _$HistoryVm with DioCancelableMixin {
   }
 
   //  去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode) {
-    CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
+  gotoCleanOrderDetailPage(BuildContext context, int id, String cleanServiceType, int serviesStatusCode) {
+    CleanOrderDetailPage.startInstance(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode);
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/history/history_vm.g.dart

@@ -6,7 +6,7 @@ part of 'history_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$historyVmHash() => r'2a0c8e7434615d19ce6f2a71d8d4847ae570c1a1';
+String _$historyVmHash() => r'89aa7cc56fe2bb8cf7a7a2d7087f3ca431417819';
 
 /// See also [HistoryVm].
 @ProviderFor(HistoryVm)

+ 12 - 7
packages/cpt_services/lib/modules/services/homeService/home_service_page.dart

@@ -1,5 +1,6 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
+import 'package:domain/entity/paid_service_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/rendering.dart';
@@ -101,8 +102,11 @@ class HomeServicePage extends HookConsumerWidget {
                         ),
                         delegate: SliverChildBuilderDelegate(
                               (context, index) {
-                            return  _buildHomeServiceItem(context, ref, state.list[index], vm).onTap((){
-                              vm.handlerGotoDetail(context: context, id: state.list[index]['id'], serviceTypeCode: state.list[index]['service_type']);
+                            return  _buildHomeServiceItem(context, ref, state.list[index] as PaidServiceList, vm).onTap((){
+                              // 去详情页面
+                              PaidServiceList paidServiceEntity = state.list[index] as PaidServiceList;
+                              PaidServiceListCategory paidServiceCategory = paidServiceEntity.category!;
+                              vm.handlerGotoDetail(context: context, id: paidServiceEntity.id!, paidServiceCategory: paidServiceCategory!);
                             });
                           },
                           childCount: state.list.length,
@@ -110,7 +114,7 @@ class HomeServicePage extends HookConsumerWidget {
                       ),
                     ],
                   ),
-                ).marginOnly(left: 15,right: 15,top: 0,bottom: 15),
+                ).marginOnly(left: 15,right: 15,top: 15,bottom: 15),
               ),
             ],
           )
@@ -118,7 +122,7 @@ class HomeServicePage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildHomeServiceItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm){
+  Widget _buildHomeServiceItem(BuildContext context, WidgetRef ref, PaidServiceList item, vm){
     return SizedBox(
       width: double.infinity,
       // height: 170,
@@ -142,10 +146,11 @@ class HomeServicePage extends HookConsumerWidget {
               Expanded(
                 child: HomeServiceCard(
                     key: UniqueKey(),
-                    itemObj: item.cast<String, dynamic>(),
+                    itemEntity: item,
+                    cleanServiceType: item.category!.type,
                     onClickColleciotn: (dynamic collectionValue) async {
-                      Log.d("点击了喜欢按钮  --id:${item['id']}- $collectionValue");
-                      int id = item['id'];
+                      Log.d("点击了喜欢按钮  --id:${item.id}- $collectionValue");
+                      int id = item.id!;
                       return await vm.handlerClickCollection(id, collectionValue);
                     }
                 ),

+ 5 - 4
packages/cpt_services/lib/modules/services/homeService/home_service_state.dart

@@ -1,3 +1,4 @@
+import 'package:domain/entity/paid_service_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class HomeServiceState {
@@ -11,8 +12,8 @@ class HomeServiceState {
   final List<String> sortByOptionsList = ["Most Likes", "Most bookmarked", "View at Most"];
   String? sortBySelectedOption;
 
-  List<Map<String, dynamic>> activeCateGoryList;
-  List<Map<String, dynamic>> list;
+  List<PaidServiceList> activeCateGoryList;
+  List<PaidServiceList> list;
 
 
   HomeServiceState({
@@ -31,8 +32,8 @@ class HomeServiceState {
     String? keyword,
     bool? isLiked,
     String? sortBySelectedOption,
-    List<Map<String, dynamic>>? activeCateGoryList,
-    List<Map<String, dynamic>>? list,
+    List<PaidServiceList>? activeCateGoryList,
+    List<PaidServiceList>? list,
   }) {
     return HomeServiceState(
       loadingState: loadingState ?? this.loadingState,

+ 129 - 122
packages/cpt_services/lib/modules/services/homeService/home_service_vm.dart

@@ -3,9 +3,12 @@ import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/newsfeed_detail_entity.dart';
+import 'package:domain/entity/paid_service_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+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/ext/auto_router_extensions.dart';
@@ -16,8 +19,10 @@ import 'package:widgets/my_checkbox_group.dart';
 import 'package:widgets/picker/option_pick_util.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../../../constants_services.dart';
 import '../../../respository/services_respository.dart';
 import '../../../router/page/services_page_router.dart';
+import '../services_vm.dart';
 import 'home_service_state.dart';
 
 part 'home_service_vm.g.dart';
@@ -55,7 +60,7 @@ class HomeServiceVm extends _$HomeServiceVm {
   @override
   HomeServiceState build(){
     // 引入数据仓库
-    // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
+    servicesRespositoryInstance = ref.read(servicesRespositoryProvider);
     final state = initState();
     Log.d("--------------------------build---------------------");
 
@@ -128,75 +133,76 @@ class HomeServiceVm extends _$HomeServiceVm {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    List<Map<String, dynamic>> list = [
-      {
-        'id':1,
-        'service_type': 0,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 30,
-        'unit': '/hr',
-        'liked': true,
-        'likes_count': 12,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':2,
-        'service_type': 1,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 'Air Conditioning Cleaning',
-        'price': 10,
-        'unit': '/unit',
-        'liked': false,
-        'likes_count': 10,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':3,
-        'service_type': 1,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 'Cleaning Services',
-        'price': 200,
-        'unit': '/hr',
-        'liked': true,
-        'likes_count': 1212,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-    ];
-    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");
-    // }
+    // List<Map<String, dynamic>> list = [
+    //   {
+    //     'id':1,
+    //     'service_type': 0,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 30,
+    //     'unit': '/hr',
+    //     'liked': true,
+    //     'likes_count': 12,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    //   {
+    //     'id':2,
+    //     'service_type': 1,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 'Air Conditioning Cleaning',
+    //     'price': 10,
+    //     'unit': '/unit',
+    //     'liked': false,
+    //     'likes_count': 10,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    //   {
+    //     'id':3,
+    //     'service_type': 1,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 'Cleaning Services',
+    //     'price': 200,
+    //     'unit': '/hr',
+    //     'liked': true,
+    //     'likes_count': 1212,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    // ];
+    // handlerResultData(true, list:list);
+
+    try {
+      //请求网络
+      Map<String, dynamic>  params = {
+        "sort": null, // 排序(desc=降序,asc=升序)
+        "sort_by": null,  // 排序(likes_count=点赞量,orders_count=下单量,clicks_count=点击量)
+        "category_id": _queryParams['category_id'],
+        "keyword": _queryParams['keyword'],
+        "page": _page,
+        "limit": _limit,
+      };
+      Log.d("请求参数------$params");
+      final result = await servicesRespositoryInstance.fetchPaidServiceDataList(params);
+      //校验成功失败
+      if (result.isSuccess) {
+        handlerResultList((result.data as PaidServiceEntity).list as List<PaidServiceList>?, 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}){
+  handlerResultData(bool isList, {List<PaidServiceList>? list, dynamic? data}){
     Future.delayed(const Duration(seconds: 1)).then((value) {
       if(isList){
         // list 数据模式
@@ -242,20 +248,20 @@ class HomeServiceVm extends _$HomeServiceVm {
     });
   }
 
-  void handlerResultList(List<GarageSaleRentList>? list, bool isLoadMore) {
+  void handlerResultList(List<PaidServiceList>? list, bool isLoadMore) {
     if (list != null && list.isNotEmpty) {
       //有数据,判断是刷新还是加载更多的数据
       if (_page == 1) {
         //刷新的方式
         state.list!.clear();
-        state.list!.addAll(list.map((item) => item.toJson()).toList());
+        state.list!.addAll(list);
         refreshController.finishRefresh();
         //更新展示的状态
         changeLoadingState(LoadState.State_Success, null);
       } else {
         //加载更多
         final allList = state.list;
-        allList!.addAll(list.map((item) => item.toJson()).toList());
+        allList!.addAll(list);
         state = state.copyWith(list: allList);
         refreshController.finishLoad();
       }
@@ -291,47 +297,50 @@ class HomeServiceVm extends _$HomeServiceVm {
 
   // 获取 homeservice 的分类选项
   Future<List<Map<String, dynamic>>> getHomeServiceCategoryOptions() async{
-    await Future.delayed(const Duration(milliseconds: 300));
-    ToastEngine.dismiss();
+    // await Future.delayed(const Duration(milliseconds: 300));
+    // ToastEngine.dismiss();
     List<Map<String, dynamic>> serviceCategoryList = [
-      {
-        'id': 1,
-        'name': 'House Cleaning Serivces',
-      },
-      {
-        'id': 2,
-        'name': 'Household Appliance Cleaning',
-      },
+    //   {
+    //     'id': 1,
+    //     'name': 'House Cleaning Serivces',
+    //   },
+    //   {
+    //     'id': 2,
+    //     'name': 'Household Appliance Cleaning',
+    //   },
     ];
 
     // 获取分类列表
-    // try {
-    //   // 加入有缓存 就取缓存
-    //   List<Map<String, dynamic>>? StorageCategoryList = SPUtil.getObjectList(
-    //       AppConstant.storageGarageCategoryList)?.cast<Map<String, dynamic>>();
-    //
-    //   if (StorageCategoryList != null && StorageCategoryList.isNotEmpty) {
-    //     Log.d("取StorageCategoryList 缓存: $StorageCategoryList ");
-    //     serviceCategoryList = StorageCategoryList;
-    //   } else {
-    //     Map<String, dynamic> params = {};
-    //     final result = await commonGarageRespositoryInstance
-    //         .fetchGarageCateGoryList(params);
-    //     if (result.isSuccess) {
-    //       final listJson = result.getListJson();
-    //       // 将 listJson 转换为 List<Map<String, dynamic>>
-    //       serviceCategoryList = (listJson as List?)
-    //           ?.map((item) => item as Map<String, dynamic>)
-    //           .toList() ?? [];
-    //       // 将 serviceCategoryList 存入缓存
-    //       Log.d("设置StorageCategoryList 缓存");
-    //       SPUtil.putObjectList(
-    //           AppConstant.storageGarageCategoryList, serviceCategoryList);
-    //     }
-    //   }
-    // } catch(error){
-    //
-    // }
+    try {
+      // 加入有缓存 就取缓存
+      List<Map<String, dynamic>>? StorageCategoryList = SPUtil.getObjectList(
+          AppConstant.storagePaidServiceCategoryList)?.cast<Map<String, dynamic>>();
+
+      if (StorageCategoryList != null && StorageCategoryList.isNotEmpty) {
+        Log.d("取StorageCategoryList 缓存: $StorageCategoryList ");
+        serviceCategoryList = StorageCategoryList;
+      } else {
+        final paidServiceLayoutVm = ref.watch(servicesVmProvider.notifier);
+        Map<String, dynamic> params = {
+          'parent_id': paidServiceLayoutVm?.state.parentCategoryId,
+        };
+        final result = await servicesRespositoryInstance.fetchServiceCateGoryList(params);
+        if (result.isSuccess) {
+
+          final listJson = result.getListJson();
+          // 将 listJson 转换为 List<Map<String, dynamic>>
+          serviceCategoryList = (listJson as List?)
+              ?.map((item) => item as Map<String, dynamic>)
+              .toList() ?? [];
+          // 将 serviceCategoryList 存入缓存
+          Log.d("设置StorageCategoryList 缓存");
+          SPUtil.putObjectList(
+              AppConstant.storagePaidServiceCategoryList, serviceCategoryList);
+        }
+      }
+    } catch(error){
+      Log.d("获取分类列表失败: $error");
+    }
     return serviceCategoryList;
   }
 
@@ -339,13 +348,13 @@ class HomeServiceVm extends _$HomeServiceVm {
   handlerClickFilterIcon(BuildContext context) async{
     List<Map<String, dynamic>> serviceCategoryList = await getHomeServiceCategoryOptions();
     // 显示弹框
-    handlerShowChooseGarageCategoryDialog(context, serviceCategoryList);
+    handlerShowChooseServiceCategoryDialog(context, serviceCategoryList);
 
   }
 
-  Future<void> handlerShowChooseGarageCategoryDialog(BuildContext context, List<Map<String, dynamic>> garageCategoryList) async{
+  Future<void> handlerShowChooseServiceCategoryDialog(BuildContext context, List<Map<String, dynamic>> categoryList) async{
     await DialogEngine.show(
-        tag: "chooseGarageSaleCategory",
+        tag: "chooseServiceCategory",
         position: DialogPosition.center,
         widget: AppCustomDialog(
           message: '',
@@ -353,7 +362,7 @@ class HomeServiceVm extends _$HomeServiceVm {
           dialogWidth: MediaQuery.of(context).size.width * 0.8,
           // contentBoxMaxHeight: 350,
           // contentBoxMinHeight: 300,
-          isShowConfirmBtn: garageCategoryList!.length > 0 ? true: false,
+          isShowConfirmBtn: categoryList!.length > 0 ? true: false,
           confirmTxt: "Ok",
           messageBuilder: (BuildContext context){
             return Container(
@@ -361,14 +370,14 @@ class HomeServiceVm extends _$HomeServiceVm {
               child: Column(
                 mainAxisAlignment: MainAxisAlignment.start,
                 crossAxisAlignment: CrossAxisAlignment.start,
-                children: garageCategoryList!.length > 0 ? [
+                children: categoryList!.length > 0 ? [
                   MyCheckboxGroup(
                       isSingleSelect: _isSingleSelect,
                       labelStyle: const TextStyle(
                         fontSize: 16,
                         fontWeight: FontWeight.w500,
                       ),
-                      items: garageCategoryList!,
+                      items: categoryList!,
                       defaultSelectedItems: [],
                       onChanged: (List<Map<String, dynamic>> selectedItems){
                         Log.d("----MyCheckboxGroup onChanged  $selectedItems");
@@ -419,16 +428,12 @@ class HomeServiceVm extends _$HomeServiceVm {
       //校验成功失败
       if (result.isSuccess) {
         // 修改 该id 的 liked 和 likes_count 字段
-        state.list!.forEach((Map<String, dynamic> element) {
-          GarageSaleRentList elementEntity = GarageSaleRentList.fromJson(element);
+        state.list!.forEach((PaidServiceList elementEntity) {
 
           if(elementEntity.id == id){
             elementEntity.liked = !elementEntity.liked!;
             elementEntity.likesCount = elementEntity.liked! ? (elementEntity.likesCount! + 1) : (elementEntity.likesCount! - 1);
           }
-
-          element = elementEntity.toJson();
-
         });
         return true;
       } else {
@@ -444,6 +449,7 @@ class HomeServiceVm extends _$HomeServiceVm {
 
   // 设置当前的 _queryParams
   setCurrentQueryParams(Map<String, dynamic> params){
+    Log.d(222);
     _queryParams.addAll(params);
   }
 
@@ -506,14 +512,15 @@ class HomeServiceVm extends _$HomeServiceVm {
   }
 
   // 去详情页面
-  void handlerGotoDetail({BuildContext? context, required int id, int serviceTypeCode= 0 }){
-    Log.d("去详情页面  $id  $serviceTypeCode");
-    if(serviceTypeCode == 0 || serviceTypeCode == 1){
+  void handlerGotoDetail({BuildContext? context, required int id, required PaidServiceListCategory paidServiceCategory }){
+    final cleanServiceType = paidServiceCategory.name!;
+    Log.d("去详情页面:  $id  $cleanServiceType");
+    if(cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code'] || cleanServiceType == servicesConstants.servicesType['airConditioner']!['code']){
       // clean service  跳转到 clean 详情页
-      appRouter.push(ServiceCleanDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode));
-    }else if(serviceTypeCode == 2){
-      // repair service 跳转到 repair 详情页
-      appRouter.push(ServiceRepairDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode));
+      appRouter.push(ServiceCleanDetailPageRoute(id: id, cleanServiceType: cleanServiceType));
+    }else {
+      // other service  跳转到 other 详情页
+      ToastEngine.show("${cleanServiceType} 类型的详情暂未开放");
     }
   }
 

+ 1 - 1
packages/cpt_services/lib/modules/services/homeService/home_service_vm.g.dart

@@ -6,7 +6,7 @@ part of 'home_service_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$homeServiceVmHash() => r'f797aaab5c87dfbcd175c7a68c483f501a518020';
+String _$homeServiceVmHash() => r'186dde40ced6727523baa7bce046d5ff436bd6c9';
 
 /// See also [HomeServiceVm].
 @ProviderFor(HomeServiceVm)

+ 23 - 22
packages/cpt_services/lib/modules/services/homeService/service_card_item.dart

@@ -1,5 +1,6 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/paid_service_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -28,16 +29,16 @@ import '../../../constants_services.dart';
 
 
 class HomeServiceCard extends StatelessWidget {
-  Map<String, dynamic>? serviceType = servicesConstants.servicesType['houseCleaning'];
-  Map<String, dynamic> itemObj;
+  String? cleanServiceType;
+  PaidServiceList itemEntity;
   double? cardHeight;
   final Function()? onTap;
   final Function(dynamic)? onClickColleciotn;
 
   HomeServiceCard({
     Key? key,
-    this.serviceType,
-    required this.itemObj,
+    this.cleanServiceType,
+    required this.itemEntity,
     this.onTap,
     this.onClickColleciotn,
     double? cardHeight,
@@ -47,16 +48,16 @@ class HomeServiceCard extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    List? card_resources = itemObj.getValue<List>("resources", [])?? [];
+    List? card_resources = itemEntity.resources?? [];
+    int card_id = itemEntity.id?? 0;
     String card_img = card_resources.length>0? card_resources[0]:"";
-    String card_title = itemObj.getValue("title", "");
-    final unit = itemObj.getValue("unit", "");
+    String card_name = itemEntity.name?? "";
 
-    int card_price = itemObj.getValue("price", "");
-    String card_created_at = itemObj.getValue("created_at", "");
-    bool card_liked = itemObj.getValue("liked", false);
-    int card_likes_count = itemObj.getValue("likes_count", 0);
-    final company_name = itemObj.getValue("company_name", "");
+    int card_price = itemEntity.lowestPrice?? 0;
+    bool card_liked = itemEntity.liked??false;
+    int card_likes_count = itemEntity.likesCount?? 0;
+
+    final company_name = itemEntity.merchant?.name?? "";
     return Column(
       children: [
         // 图片
@@ -88,7 +89,7 @@ class HomeServiceCard extends StatelessWidget {
                 child: SizedBox(
                   height: 30.ap,
                   child: MyTextView(
-                    card_title,
+                    card_name,
                     maxLines: 2,
                     isTextEllipsis: true,
                     textAlign: TextAlign.left,
@@ -132,15 +133,15 @@ class HomeServiceCard extends StatelessWidget {
                       isFontMedium: true,
                       marginLeft: 2,
                     ),
-                    MyTextView(
-                      '$unit',
-                      maxLines: 1,
-                      isTextEllipsis: true,
-                      textAlign: TextAlign.start,
-                      textColor: ColorUtils.string2Color('#666666'),
-                      fontSize: 11,
-                      isFontMedium: true,
-                    ),
+                    // MyTextView(
+                    //   '$',
+                    //   maxLines: 1,
+                    //   isTextEllipsis: true,
+                    //   textAlign: TextAlign.start,
+                    //   textColor: ColorUtils.string2Color('#666666'),
+                    //   fontSize: 11,
+                    //   isFontMedium: true,
+                    // ),
                   ],
                 ),
               ),

+ 5 - 5
packages/cpt_services/lib/modules/services/inProgress/in_progress_page.dart

@@ -45,7 +45,7 @@ class InProgressPage extends HookConsumerWidget {
     final state = ref.watch(inProgressVmProvider);
     // final appConfigState = ref.watch(appConfigServiceProvider)
 
-    int serviceTypeCode = servicesConstants.servicesType['houseCleaning']?['code'];
+    String cleanServiceType = servicesConstants.servicesType['houseCleaning']?['code'];
     int serviceStatusCode = servicesConstants.servicesStatus['1']?['code'];
 
     useEffect(() {
@@ -90,12 +90,12 @@ class InProgressPage extends HookConsumerWidget {
                 SliverList(
                   delegate: SliverChildBuilderDelegate(
                     (context, index) {
-                      return _buildInProgressItem(context, ref, state.list[index], vm, serviceTypeCode, serviceStatusCode).onTap(() {
+                      return _buildInProgressItem(context, ref, state.list[index], vm,  cleanServiceType, serviceStatusCode).onTap(() {
                         vm.gotoCleanOrderDetailPage(
                           context,
                           state.list[index].id != null ? int.tryParse(state.list[index].id!) ?? 0 : 0,
-                          0,
-                          0,
+                          cleanServiceType,
+                          serviceStatusCode,
                         );
                       });
                     },
@@ -108,7 +108,7 @@ class InProgressPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildInProgressItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, int serviceTypeCode, int serviceStatusCode) {
+  Widget _buildInProgressItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, String cleanServiceType, int serviceStatusCode) {
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,

+ 2 - 2
packages/cpt_services/lib/modules/services/inProgress/in_progress_vm.dart

@@ -196,7 +196,7 @@ class InProgressVm extends _$InProgressVm with DioCancelableMixin {
   }
 
   //  去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode) {
-    CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
+  gotoCleanOrderDetailPage(BuildContext context, int id, String cleanServiceType, int serviesStatusCode) {
+    CleanOrderDetailPage.startInstance(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode);
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/inProgress/in_progress_vm.g.dart

@@ -6,7 +6,7 @@ part of 'in_progress_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$inProgressVmHash() => r'f3c62cd304779aec9504c09d4f83e8b32787073a';
+String _$inProgressVmHash() => r'a68e56ab4116a9868f38b5389e1527bfc2453975';
 
 /// See also [InProgressVm].
 @ProviderFor(InProgressVm)

+ 5 - 4
packages/cpt_services/lib/modules/services/repair/repair_page.dart

@@ -27,14 +27,15 @@ final GlobalKey<ExtendedNestedScrollViewState> extendedNestedScrollViewKey =
 GlobalKey<ExtendedNestedScrollViewState>();
 @RoutePage()
 class RepairPage extends HookConsumerWidget with WidgetsBindingObserver {
-  RepairPage({Key? key}) : super(key: key);
+  int parentCategoryId = 0; //父级分类id
+  RepairPage({Key? key, required this.parentCategoryId}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance({BuildContext? context, required int parentCategoryId}) {
     if (context != null) {
-      context.router.push( RepairPageRoute());
+      context.router.push( RepairPageRoute(parentCategoryId:parentCategoryId));
     } else {
-      appRouter.push( RepairPageRoute());
+      appRouter.push( RepairPageRoute(parentCategoryId:parentCategoryId));
     }
   }
 

+ 5 - 5
packages/cpt_services/lib/modules/services/repair_history/history_page.dart

@@ -46,7 +46,7 @@ class RepairHistoryPage extends HookConsumerWidget {
     final state = ref.watch(repairHistoryVmProvider);
     // final appConfigState = ref.watch(appConfigServiceProvider)
 
-    int serviceTypeCode = servicesConstants.servicesType['houseCleaning']?['code'];
+    String cleanServiceType = servicesConstants.servicesType['houseCleaning']?['code'];
     int serviceStatusCode = servicesConstants.servicesStatus['2']?['code'];
 
 
@@ -97,13 +97,13 @@ class RepairHistoryPage extends HookConsumerWidget {
                           ref,
                           state.list[index],
                           vm,
-                          serviceTypeCode,
+                          cleanServiceType,
                           serviceStatusCode,
                       ).onTap((){
                         // vm.gotoCleanOrderDetailPage(
                         //   context,
                         //   state.list?[index]['id'],
-                        //   serviceTypeCode,
+                        //   cleanServiceType,
                         //   serviceStatusCode,
                         // );
                       });
@@ -118,7 +118,7 @@ class RepairHistoryPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildRepairHistoryItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, int serviceTypeCode, int serviceStatusCode){
+  Widget _buildRepairHistoryItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, String cleanServiceType, int serviceStatusCode){
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,
@@ -137,7 +137,7 @@ class RepairHistoryPage extends HookConsumerWidget {
         key: UniqueKey(),
         cardHeight: 150.0,
         serviceId: item['id'],
-        serviceTypeCode: serviceTypeCode,
+        cleanServiceType: cleanServiceType,
         serviceStatusCode: serviceStatusCode,
         itemObj: item.cast<String, dynamic>(),
         onClickCard: (dynamic value) async {

+ 2 - 2
packages/cpt_services/lib/modules/services/repair_history/history_vm.dart

@@ -300,7 +300,7 @@ class RepairHistoryVm extends _$RepairHistoryVm {
   }
 
   // 去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode){
-    CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
+  gotoCleanOrderDetailPage(BuildContext context, int id, String cleanServiceType, int serviesStatusCode){
+    CleanOrderDetailPage.startInstance(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode);
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/repair_history/history_vm.g.dart

@@ -6,7 +6,7 @@ part of 'history_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$repairHistoryVmHash() => r'a85e3ce352d40334a0721d399e66a94c49f2869e';
+String _$repairHistoryVmHash() => r'0efc4fce87cd9f6fd4a3946d43b3cacef966aa00';
 
 /// See also [RepairHistoryVm].
 @ProviderFor(RepairHistoryVm)

+ 1 - 1
packages/cpt_services/lib/modules/services/repair_homeService/home_service_page.dart

@@ -102,7 +102,7 @@ class RepairHomeServicePage extends HookConsumerWidget {
                         delegate: SliverChildBuilderDelegate(
                               (context, index) {
                             return  _buildRepairHomeServiceItem(context, ref, state.list[index], vm).onTap((){
-                              vm.handlerGotoDetail(context: context, id: state.list[index]['id'], serviceTypeCode: state.list[index]['service_type']);
+                              vm.handlerGotoDetail(context: context, id: state.list[index]['id'], cleanServiceType: state.list[index]['service_type']);
                             });
                           },
                           childCount: state.list.length,

+ 47 - 51
packages/cpt_services/lib/modules/services/repair_homeService/home_service_vm.dart

@@ -88,8 +88,6 @@ class RepairHomeServiceVm extends _$RepairHomeServiceVm {
   // 下拉刷新
   Future onRefresh() async {
     // 当前pageView 页面正处于显示状态
-    Log.d("----forsale_vm-----onRefresh ");
-    // await Future.delayed(const Duration(seconds: 2));
     _page = 1;
     getListData();
   }
@@ -128,60 +126,61 @@ class RepairHomeServiceVm extends _$RepairHomeServiceVm {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    List<Map<String, dynamic>> list = [
-      {
-        'id':1,
-        'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 'Repair Services',
-        'price': 30,
-        'unit': '/hr',
-        'liked': true,
-        'likes_count': 12,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':2,
-        'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 'Repair Air Conditioning',
-        'price': 10,
-        'unit': '/unit',
-        'liked': false,
-        'likes_count': 10,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':3,
-        'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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': 'Repair air Conditioner Services',
-        'price': 200,
-        'unit': '/hr',
-        'liked': true,
-        'likes_count': 1212,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-    ];
-    handlerResultData(true, list:list);
+    // List<Map<String, dynamic>> list = [
+    //   {
+    //     'id':1,
+    //     'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 'Repair Services',
+    //     'price': 30,
+    //     'unit': '/hr',
+    //     'liked': true,
+    //     'likes_count': 12,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    //   {
+    //     'id':2,
+    //     'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 'Repair Air Conditioning',
+    //     'price': 10,
+    //     'unit': '/unit',
+    //     'liked': false,
+    //     'likes_count': 10,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    //   {
+    //     'id':3,
+    //     'service_type': 2,  // 0 房屋保洁 1 空调保洁  2 维修
+    //     'cover_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': 'Repair air Conditioner Services',
+    //     'price': 200,
+    //     'unit': '/hr',
+    //     'liked': true,
+    //     'likes_count': 1212,
+    //     'company_name': 'HONG YE GROUP PTE LTD',
+    //   },
+    // ];
+    // handlerResultData(true, list:list);
 
     // try {
     //   //请求网络
     //   Map<String, dynamic>  params = {
-    //     "type": 1,  // 类型(1=Sale,2=Rent)
+    //     "sort": null, // 排序(desc=降序,asc=升序)
+    //     "sort_by": null,  // 排序(likes_count=点赞量,orders_count=下单量,clicks_count=点击量)
     //     "category_id": _queryParams['category_id'],
     //     "keyword": _queryParams['keyword'],
     //     "page": _page,
     //     "limit": _limit,
     //   };
     //   Log.d("请求参数------$params");
-    //   final result = await servicesRespositoryInstance.fetchGarageDataList(params);
+    //   final result = await servicesRespositoryInstance.fetchRepairServiceList(params);
     //   //校验成功失败
     //   if (result.isSuccess) {
-    //     // handlerResultList((result.data as GarageSaleRentEntity).list as List<GarageSaleRentList>, isLoadMore ?? false);
+    //     handlerResultList((result.data as PaidServiceEntity).list as List<PaidServiceList>?, isLoadMore ?? false);
     //   } else {
     //     String errorMessage = result.errorMsg!;
     //     changeLoadingState(LoadState.State_Error, errorMessage);
@@ -502,14 +501,11 @@ class RepairHomeServiceVm extends _$RepairHomeServiceVm {
   }
 
   // 去详情页面
-  void handlerGotoDetail({BuildContext? context, required int id, int serviceTypeCode= 0 }){
-    Log.d("去详情页面  $id  $serviceTypeCode");
-    if(serviceTypeCode == 0 || serviceTypeCode == 1){
+  void handlerGotoDetail({BuildContext? context, required int id, String? cleanServiceType }){
+    Log.d("去详情页面  $id  $cleanServiceType");
+    if(cleanServiceType == 0 || cleanServiceType == 1){
       // clean service  跳转到 clean 详情页
-      appRouter.push(ServiceCleanDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode));
-    }else if(serviceTypeCode == 2){
-      // repair service 跳转到 repair 详情页
-      appRouter.push(ServiceRepairDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode));
+      appRouter.push(ServiceCleanDetailPageRoute(id: id, cleanServiceType: cleanServiceType!));
     }
   }
 

+ 1 - 1
packages/cpt_services/lib/modules/services/repair_homeService/home_service_vm.g.dart

@@ -7,7 +7,7 @@ part of 'home_service_vm.dart';
 // **************************************************************************
 
 String _$repairHomeServiceVmHash() =>
-    r'a3b0fad948ce8102784f895ebc097ee87ffe844d';
+    r'184ab2f5e837316c41329192c1079fe183b0b9d0';
 
 /// See also [RepairHomeServiceVm].
 @ProviderFor(RepairHomeServiceVm)

+ 5 - 5
packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_page.dart

@@ -46,7 +46,7 @@ class RepairInProgressPage extends HookConsumerWidget {
     final state = ref.watch(repairInProgressVmProvider);
     // final appConfigState = ref.watch(appConfigServiceProvider)
 
-    int serviceTypeCode = servicesConstants.servicesType['houseCleaning']?['code'];
+    String cleanServiceType = servicesConstants.servicesType['houseCleaning']?['code'];
     int serviceStatusCode = servicesConstants.servicesStatus['1']?['code'];
 
     useEffect(() {
@@ -96,13 +96,13 @@ class RepairInProgressPage extends HookConsumerWidget {
                           ref,
                           state.list[index],
                           vm,
-                          serviceTypeCode,
+                          cleanServiceType,
                           serviceStatusCode
                       ).onTap((){
                         // vm.gotoCleanOrderDetailPage(
                         //     context,
                         //     state.list?[index]['id'],
-                        //     serviceTypeCode,
+                        //     cleanServiceType,
                         //     serviceStatusCode
                         // );
                       });
@@ -117,7 +117,7 @@ class RepairInProgressPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildRepairInProgressItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, int serviceTypeCode, int serviceStatusCode){
+  Widget _buildRepairInProgressItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, String cleanServiceType, int serviceStatusCode){
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,
@@ -136,7 +136,7 @@ class RepairInProgressPage extends HookConsumerWidget {
           key: UniqueKey(),
           cardHeight: 120.0,
           serviceId: item['id'],
-          serviceTypeCode: serviceTypeCode,
+          cleanServiceType: cleanServiceType,
           serviceStatusCode: serviceStatusCode,
           itemObj: item.cast<String, dynamic>(),
           onClickCard: (dynamic value) async {

+ 2 - 2
packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_vm.dart

@@ -300,7 +300,7 @@ class RepairInProgressVm extends _$RepairInProgressVm {
   }
 
   //  去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode){
-    CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
+  gotoCleanOrderDetailPage(BuildContext context, int id, String cleanServiceType, int serviesStatusCode){
+    CleanOrderDetailPage.startInstance(id: id, cleanServiceType: cleanServiceType, serviesStatusCode: serviesStatusCode);
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/repair_inProgress/in_progress_vm.g.dart

@@ -7,7 +7,7 @@ part of 'in_progress_vm.dart';
 // **************************************************************************
 
 String _$repairInProgressVmHash() =>
-    r'968f6c5d90c2f5e7b510e0430617bacbff3062d4';
+    r'a35790c3e5285086a1bf7792c6c7d3c704e4bfa9';
 
 /// See also [RepairInProgressVm].
 @ProviderFor(RepairInProgressVm)

+ 140 - 138
packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_page.dart

@@ -1,8 +1,7 @@
 import 'package:cpt_services/components/chooseAirConditionContent.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
-import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
-import 'package:domain/entity/garage_sale_rent_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -22,6 +21,7 @@ import 'package:widgets/my_like_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
+import 'package:shared/utils/richText_utils.dart';
 
 import '../../../components/chooseHouseCleanContent.dart';
 import '../../../components/user_evaluate_card_item.dart';
@@ -33,15 +33,15 @@ import '../../../router/page/services_page_router.dart';
 @RoutePage()
 class ServiceCleanDetailPage extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
-  const ServiceCleanDetailPage({Key? key,@PathParam('id') required this.id, @PathParam('serviceTypeCode') required this.serviceTypeCode}) : super(key: key);
+  const ServiceCleanDetailPage({Key? key,@PathParam('id') required this.id, @PathParam('cleanServiceType') required this.cleanServiceType}) : super(key: key);
   // 启动当前页面
-  static void startInstance({BuildContext? context, int? id, int? serviceTypeCode = 0}) {
+  static void startInstance({BuildContext? context, int? id, String? cleanServiceType}) {
     if (context != null) {
-      context.router.push(ServiceCleanDetailPageRoute(id: id!, serviceTypeCode: serviceTypeCode!));
+      context.router.push(ServiceCleanDetailPageRoute(id: id!, cleanServiceType: cleanServiceType!));
     } else {
-      appRouter.push(ServiceCleanDetailPageRoute(id: id!, serviceTypeCode: serviceTypeCode!));
+      appRouter.push(ServiceCleanDetailPageRoute(id: id!, cleanServiceType: cleanServiceType!));
     }
   }
 
@@ -53,11 +53,12 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
     final String pageTitle = 'Clean Details';
     GlobalKey _likeButtonKey = GlobalKey<MyLikeButtonState>();
 
-    Map<String, dynamic>? detailInfo = state.datas?? null;
-    String title =  detailInfo?['title']?? '';
+    PaidServiceDetailEntity? detailInfo = state.datas?? null;
+
 
     useEffect((){
-      vm.setInitPageData(id: id, serviceTypeCode: serviceTypeCode,);
+      vm.setInitPageData(id: id, cleanServiceType: cleanServiceType);
+
       // 组件挂载时执行 - 执行接口请求
       Future.microtask(() => vm.initPageData());
       return () {
@@ -126,16 +127,19 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildContentBox(BuildContext context, WidgetRef ref, Map<String, dynamic> detailInfo) {
-    List<String> resources = detailInfo?['resources'].cast<String>()??[];
-    String title =  detailInfo?['title']??'';
-    double score = detailInfo?['score']?? 5.0;
+  Widget _buildContentBox(BuildContext context, WidgetRef ref, PaidServiceDetailEntity detailInfo) {
+    final String title = detailInfo?.name??'';
+    List<String> resources = detailInfo!.resources?.cast<String>()??[];
+    double evaluationsAvgScore = (detailInfo?.evaluationsAvgScore?? 5.0).toDouble();
+    final hilightStr = detailInfo?.highlight??'';
+    final description =  RichtextUtils.getHandleResult(detailInfo?.description??'');
 
-    final hilightStr = detailInfo?['hilightStr']??'On call, at the fastest 30 minutes to come to the door';
+    final String merchantName = detailInfo?.merchant?.name??'';
 
-
-    String description = detailInfo?['description']??'';
+    List<dynamic> evaluations = detailInfo?.evaluations??[];
+    bool hasEvaluations = evaluations.isNotEmpty;
     CarouselSliderController buttonCarouselController = CarouselSliderController();
+
     return Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
@@ -203,7 +207,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         MyTextView(
-                          "House Cleaning Services",
+                          '$title',
                           textColor: context.appColors.textBlack,
                           fontSize: 18,
                           isFontBold: true,
@@ -214,7 +218,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                           crossAxisAlignment: CrossAxisAlignment.center,
                           children: [
                             AnimatedRatingStars(
-                              initialRating: score,
+                              initialRating: evaluationsAvgScore,
                               onChanged: (rating) {
                               },
                               readOnly: true,
@@ -229,7 +233,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                               animationCurve: Curves.easeInOut,
                             ),
                             MyTextView(
-                              "${score}",
+                              "${evaluationsAvgScore}",
                               textColor: context.appColors.textBlack,
                               fontSize: 16,
                               isFontMedium: true,
@@ -238,7 +242,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                           ],
                         ),
                         MyTextView(
-                          "HONG YE GROUP PTE LTD",
+                          '$merchantName',
                           textColor: context.appColors.textDarkGray999,
                           fontSize: 12,
                           isFontRegular: true,
@@ -253,127 +257,127 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
               //  室内清洁选择服务 或者 空调清洁选择空调选项
               _buildSelectHouseCleanOrAirConditioner(context, ref, detailInfo),
               // user Reviews
-              _buildUserReviews(context, ref, detailInfo),
-              // 介绍图
-              Padding(
-                padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
-                child: Column(
-                  children: List.generate(6, (index) {
-                    // 创建一个映射来关联字符串和资源
-                    final Map<String, String> assetMap = {
-                      'serviceDetail01': Assets.serviceDetail01,
-                      'serviceDetail02': Assets.serviceDetail02,
-                      'serviceDetail03': Assets.serviceDetail03,
-                      'serviceDetail04': Assets.serviceDetail04,
-                      'serviceDetail05': Assets.serviceDetail05,
-                      'serviceDetail06': Assets.serviceDetail06,
-                    };
-                    String curDetailStr = 'serviceDetail0${(index + 1)}';
-                    return MyAssetImage(
-                      assetMap[curDetailStr]!,
-                      width: SizeConfig().screenWidth,
-                      fit: BoxFit.cover,
-                    );
-                  }).toList(),
-                )
-              ),
+              hasEvaluations? _buildUserReviews(context, ref, detailInfo): const SizedBox.shrink(),
+              // description
+              Html(data: description),
             ],
           ),
         ]
     );
   }
 
-  Widget _buildUserReviews(BuildContext context, WidgetRef ref, Map<String, dynamic> detailInfo) {
+  // user Reviews
+  Widget _buildUserReviews(BuildContext context, WidgetRef ref, PaidServiceDetailEntity detailInfo) {
     final vm = ref.read(serviceCleanDetailVmProvider.notifier);
     final state = ref.watch(serviceCleanDetailVmProvider);
     int reviewScoreMaxNum = 3;
     double reviewScoreItemCardHeight = 275;
+    double reviewScoreItemCardWidth = 300;
+    List<PaidServiceDetailEvaluations>? evaluations = detailInfo?.evaluations;
 
+    if (evaluations == null || evaluations.isEmpty) {
+      return const SizedBox.shrink();
+    }else {
+      if(evaluations.length >= reviewScoreMaxNum){
+        reviewScoreMaxNum = reviewScoreMaxNum;
+        reviewScoreItemCardWidth = 300;
+      }else{
+        reviewScoreMaxNum = evaluations.length;
+        reviewScoreItemCardWidth = (context.screenSize.width! - 32) / reviewScoreMaxNum;
+      }
 
-    Map<String, dynamic> item = {
-      'name': "User Sandy",
-      'avatar': "",
-      'score': 5.0,
-      'card_created_at': "14 Oct 2024 15:00",
-      'content': "This aunt is very careful because I haven't been home for three or four months. The house is",
-      'resources': [],
-    };
-    return Container(
-      width: context.screenSize.width! * reviewScoreMaxNum,
-      height: reviewScoreItemCardHeight,
-      child: Column(
-        children: [
-          Container(
-            padding: const EdgeInsets.only(left: 16, right: 16, top: 16,bottom: 0),
-            color: context.appColors.whiteBG,
-            child: Row(
-              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-              crossAxisAlignment: CrossAxisAlignment.center,
-              children: [
-                MyTextView(
-                  "User Reviews",
-                  textColor: context.appColors.textBlack,
-                  fontSize: 17,
-                  isFontBold: true,
-                ),
-                Wrap(
-                  crossAxisAlignment: WrapCrossAlignment.center,
-                  spacing: 5,
-                  children: [
-                    MyTextView(
-                      "All",
-                      textColor: context.appColors.textDarkGray999,
-                      fontSize: 14,
-                      isFontRegular: true,
-                    ),
-                    MyAssetImage(
-                      Assets.serviceArrowRightIcon,
-                      width: 12.5,
-                      height: 10,
-                      color: context.appColors.textPrimary,
-                    ),
-                  ]
-                ),
-              ],
-            ).onTap((){
-              vm.gotoUserReviewsPage(context, id, serviceTypeCode);
-            }),
-          ),
-          Expanded(
-            child: SingleChildScrollView(
-              scrollDirection: Axis.horizontal,
-              physics: const BouncingScrollPhysics(),
-              child: Container(
-                color: context.appColors.whiteBG,
-                padding: const EdgeInsets.only(left: 16, right: 16, top: 0,bottom: 16),
-                child: Row(
-                  children: List.generate(reviewScoreMaxNum, (index){
-                    return _buildserviceEvaluateListItem(context, ref, item, vm, 300);
-                  }),
+      Log.d("evaluations 数量:${evaluations.length}");
+      Log.d("evaluation 最大展示数量:$reviewScoreMaxNum");
+
+      Map<String, dynamic> item = {
+        'name': "User Sandy",
+        'avatar': "",
+        'score': 5.0,
+        'card_created_at': "14 Oct 2024 15:00",
+        'content': "This aunt is very careful because I haven't been home for three or four months. The house is",
+        'resources': [],
+      };
+
+      return Container(
+        width: context.screenSize.width! * reviewScoreMaxNum,
+        height: reviewScoreItemCardHeight,
+        child: Column(
+          children: [
+            Container(
+              padding: const EdgeInsets.only(left: 16, right: 16, top: 16,bottom: 0),
+              color: context.appColors.whiteBG,
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  MyTextView(
+                    "User Reviews",
+                    textColor: context.appColors.textBlack,
+                    fontSize: 17,
+                    isFontBold: true,
+                  ),
+                  Wrap(
+                      crossAxisAlignment: WrapCrossAlignment.center,
+                      spacing: 5,
+                      children: [
+                        MyTextView(
+                          "All",
+                          textColor: context.appColors.textDarkGray999,
+                          fontSize: 14,
+                          isFontRegular: true,
+                        ),
+                        MyAssetImage(
+                          Assets.serviceArrowRightIcon,
+                          width: 12.5,
+                          height: 10,
+                          color: context.appColors.textPrimary,
+                        ),
+                      ]
+                  ),
+                ],
+              ).onTap((){
+                vm.gotoUserReviewsPage(context, id, cleanServiceType);
+              }),
+            ),
+            // evaluate list
+            Expanded(
+              child: SingleChildScrollView(
+                scrollDirection: Axis.horizontal,
+                physics: const BouncingScrollPhysics(),
+                child: Container(
+                  color: context.appColors.whiteBG,
+                  padding: const EdgeInsets.only(left: 16, right: 16, top: 0,bottom: 16),
+                  child: Row(
+                    children: List.generate(reviewScoreMaxNum, (index){
+                      PaidServiceDetailEvaluations item = evaluations[index];
+                      return _buildserviceEvaluateListItem(context, ref, item, vm, reviewScoreItemCardWidth);
+                    }),
+                  ),
                 ),
               ),
-            ),
-          )
-        ],
-      ),
-    );
+            )
+          ],
+        ),
+      );
+    }
   }
 
-  Widget _buildserviceEvaluateListItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, double cardWidth){
-    String card_name = item?['name']?? "User Sandy";
-    String card_avatar = item?['avatar']?? "";
-    double card_score = item?['score']?? 5.0;
-    String card_created_at = item?['card_created_at']?? "14 Oct 2024 15:00";
-    String card_content = item.getValue("content", "This aunt is very careful because I haven't been home for three or four months. The house is");
-    List? card_resources =  ['https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500','https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500','https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500','https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500'];
+  Widget _buildserviceEvaluateListItem(BuildContext context, WidgetRef ref, PaidServiceDetailEvaluations item, vm, double cardWidth){
+    int? card_id = item.id?? null;
+    double card_score = (item.score?? 5.0).toDouble();
+    String card_comment = item.comment??"";
+    List<String>? card_resources = item.resources??[];
+    String card_created_at = item.createdAt??"";
+    PaidServiceDetailEvaluationsAccount? account=item.account??null;
+    String card_name = account?.name??"";
+    String card_avatar = account?.avatar??"";
 
     // Log.d("card_resources  $card_resources");
     return LayoutBuilder(
       builder: (context, constraints) {
         final maxWidth = constraints.maxWidth;
         final maxHeight = constraints.maxHeight;
-        // Log.d("8933 $maxWidth  $maxHeight");
-        Log.d("55555 $cardWidth");
+        Log.d("maxWidth  $maxWidth");
         return Container(
           margin: const EdgeInsets.only(top: 10),
           width: cardWidth,
@@ -400,7 +404,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                   avator: card_avatar,
                   score: card_score,
                   time: card_created_at,
-                  content: card_content,
+                  content: card_comment,
                   contentTextMaxLines: 2,
                   imageUrls: card_resources,
                 ),
@@ -412,10 +416,11 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildSelectHouseCleanOrAirConditioner(BuildContext context, WidgetRef ref, Map<String, dynamic> detailInfo) {
-    if(serviceTypeCode == servicesConstants.servicesType['houseCleaning']!['code']){
+  Widget _buildSelectHouseCleanOrAirConditioner(BuildContext context, WidgetRef ref, PaidServiceDetailEntity detailInfo) {
+    if(cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code']){
+      List<PaidServiceDetailProducts>? houseCleanList = detailInfo?.products??[];
       // 室内清洁
-      return Column(
+      return houseCleanList.isNotEmpty? Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
           Padding(
@@ -441,15 +446,12 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
               ],
             ),
           ),
-          ChooseHouseCleanContent(id: id, serviceTypeCode: serviceTypeCode,),
+          ChooseHouseCleanContent(id: id, cleanServiceType: cleanServiceType, products: houseCleanList),
         ],
-      );
-    }else if(serviceTypeCode == servicesConstants.servicesType['airConditioner']!['code']){
-      // 空调清洁
-      // return ChooseAirConditionContent(id: id, serviceTypeCode: serviceTypeCode);
-    }else if(serviceTypeCode == servicesConstants.servicesType['repaire']!['code']){
-      // 维修
-      return SizedBox.shrink();
+      ): SizedBox.shrink();
+    }else if(cleanServiceType == servicesConstants.servicesType['airConditioner']!['code']){
+      // 空调清洁  页面中没有直接展示 选择数量的  直接在弹窗中选择了
+      // return ChooseAirConditionContent(id: id, cleanServiceType: cleanServiceType);
     }
     return SizedBox.shrink();
   }
@@ -459,14 +461,14 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
       WidgetRef ref,
       likeButtonKey,
       {
-        required Map<String, dynamic> detailInfo,
+        required PaidServiceDetailEntity detailInfo,
       }
       ) {
     final vm = ref.read(serviceCleanDetailVmProvider.notifier);
 
-    int? likes_count =  detailInfo['likesCount']??0;
-    bool isLiked = detailInfo['isLiked']??false;
-    final contact = detailInfo['contact']??'+8613563656325';
+    int? likes_count = 0;
+    bool isLiked = false;
+    final contact = '+8613563656325';
 
     final _likes_count = useState<int>(likes_count!);
     final _isLiked = useState<bool>(isLiked);
@@ -502,7 +504,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                         customIconHeight: 18,
                         onLike: () async {
                           Log.d('点击了like button');
-                          int id = detailInfo!['id'] as int;
+                          int id = detailInfo.id!;
                           final isSuccess = await vm.handlerClickCollection(context, id, true);
                           if(isSuccess!=null && isSuccess){
                             // 成功
@@ -563,7 +565,7 @@ class ServiceCleanDetailPage extends HookConsumerWidget {
                 ),
               ),
             ).onTap((){
-              vm.handlerClickBookNow(context, id: id , serviceTypeCode: serviceTypeCode);
+              vm.handlerClickBookNow(context, id: id , cleanServiceType: cleanServiceType,);
             }),
           ),
         ],

+ 3 - 2
packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_state.dart

@@ -1,4 +1,5 @@
 import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class ServiceCleanDetailState {
@@ -13,7 +14,7 @@ class ServiceCleanDetailState {
   final int? id;
   final String? type;
   double? totalPrice;
-  Map<String, dynamic>? datas;
+  PaidServiceDetailEntity? datas;
 
   ServiceCleanDetailState({
     this.loadingState = LoadState.State_Loading,
@@ -27,7 +28,7 @@ class ServiceCleanDetailState {
   });
 
   ServiceCleanDetailState copyWith({
-    Map<String, dynamic>? datas,
+    PaidServiceDetailEntity? datas,
     LoadState? loadingState,
     String? errorMessage,
     LoadState? dialogLoadingState,

+ 61 - 63
packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_vm.dart

@@ -1,10 +1,12 @@
 
 import 'dart:async';
 
+import 'package:cpt_services/components/chooseAirConditionContent_vm.dart';
 import 'package:cpt_services/components/chooseVisitTimeContent.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_basic/basic_export.dart';
@@ -12,6 +14,7 @@ import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/ext_dart.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -22,6 +25,7 @@ import 'package:widgets/dialog/dialog_content_wrap.dart';
 import '../../../components/chooseAirConditionContent.dart';
 import '../../../components/chooseAirConditionTitle.dart';
 import '../../../components/chooseHouseCleanContent.dart';
+import '../../../components/chooseHouseCleanContent_vm.dart';
 import '../../../components/chooseHouseCleanTitle.dart';
 import '../../../constants_services.dart';
 import '../../../respository/services_respository.dart';
@@ -41,8 +45,8 @@ final _chooseAirCleanDialogGlobalKey = GlobalKey<DialogContentWrapState>();
 class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
   late ServicesRespository serviceRespositoryInstance;
 
-  int _detailId = 0;
-  int _detailServiceTypeCode = 0;
+  int? _detailId;
+  String? _cleanServiceType;
 
   bool _needShowPlaceholder = false; //是否展示LoadingView
   int _page = 1;  // 当前页
@@ -84,14 +88,14 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
     );
   }
 
-  setInitPageData({required int id, required int serviceTypeCode}){
+  setInitPageData({required int id, required String cleanServiceType}){
+    Log.d("service_clean_detail 设置 initpagedata ---  id:$id cleanServiceType:$cleanServiceType");
     _detailId = id;
-    _detailServiceTypeCode = serviceTypeCode;
+    _cleanServiceType = cleanServiceType!;
   }
   
   // 初始化页面数据
   initPageData() {
-    Log.d("----for_sale_vm-----initPageData   ${state.loadingState}");
     onRefresh();
   }
 
@@ -141,42 +145,13 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-
-    // await Future.delayed(const Duration(milliseconds: 1500));
-    //
-    // final Map<String, dynamic> detailData = {
-    //   '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',
-    //   'description':'Electronic keyboards for sale. I will attend together with the booth.\$10 per day usage Negotiable usage',
-    //   'isCollection': true,
-    //   'contactType': 'WhatsApp',
-    //   'contactInfo': '+1 123456789',
-    //   'collection_num': 12,
-    //   'publisher': 'William Jefferson',
-    //   'publisher_avatar': 'https://img1.baidu.com/it/u=3890726495,1572750319&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
-    //   'publisher_time': 'June 17,2024 at 7:23 PM'
-    // };
-
-    // state = state.copyWith(datas: GarageSaleRentDetailEntity(
-    // ));
-    //
-    // changeLoadingState(LoadState.State_Success, null);
-    //
-    // refreshController.finishRefresh();
-    //
-    // // 最后赋值
-    // _needShowPlaceholder = false;
-
-
     try {
       Map<String, dynamic> params = {
         "id": _detailId,
       };
       final result = await serviceRespositoryInstance.fetchPaidServiceCleanDetailInfo(params);
       if(result.isSuccess){
-        state = state.copyWith(datas: result.data as Map<String, dynamic>);
+        state = state.copyWith(datas: result.data as PaidServiceDetailEntity);
         changeLoadingState(LoadState.State_Success, null);
         refreshController.finishRefresh();
       } else {
@@ -197,9 +172,9 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
   // 点击了底部的收藏按钮
   Future<bool?> handlerClickCollection(BuildContext? context, int id, bool isCollection) async{
     // var vm;
-    // if(_detailServiceTypeCode == "forSale"){
+    // if(_cleanServiceType == "forSale"){
     //   // vm = ref.read(forsaleVmProvider.notifier);
-    // }else if(_detailServiceTypeCode == "forRent"){
+    // }else if(_cleanServiceType == "forRent"){
     //   vm = ref.read(forrentVmProvider.notifier);
     // }
     // try {
@@ -232,8 +207,8 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
 
   // 点击 whatsapp
   handlerClickWhatsapp(BuildContext? context,String contactType, String title, int price){
-    // 假设你有一个获取 WhatsApp 号码的方法
-    String whatsappNumber = getContactNumber(contactType); // 你需要实现这个方法
+    // 获取 WhatsApp 号码
+    String whatsappNumber = getContactNumber(contactType); 
     // 构建消息并进行编码
     String message = Uri.encodeComponent("Hello, I am interested in your listing: $title for $price.");
     // 打开WhatsApp
@@ -274,17 +249,26 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
   }
 
   // 点击了 Book Now 按钮
-  handlerClickBookNow(BuildContext context, {int? id, int? serviceTypeCode} ){
+  handlerClickBookNow(BuildContext context, {int? id, String? cleanServiceType} ){
     final detailId = id ?? _detailId;
-    final detailServiceTypeCode = serviceTypeCode ?? _detailServiceTypeCode;   // 0 房屋清洁  1 空调清洁  2 维修
-    if(detailServiceTypeCode == servicesConstants.servicesType['houseCleaning']!['code']){
+    final cleanType = cleanServiceType ?? _cleanServiceType;   // 0 房屋清洁  1 空调清洁  2 维修
+    if(cleanType == servicesConstants.servicesType['houseCleaning']!['code']){
       // 房屋清洁
-      handlerShowChooseCleanConditionerDialog(context);
-    }else if(detailServiceTypeCode == servicesConstants.servicesType['airConditioner']!['code']){
+      final chooseHouseCleanContentVm= ref.read(chooseHouseCleanContentVmProvider.notifier);
+      if(!chooseHouseCleanContentVm.state.hasCheckdService){
+        // 详情页面中没有选择 服务项目 此时需要弹出底部弹框供选择
+        // handlerShowChooseCleanConditionerDialog(context);
+        ToastEngine.show("Please select service");
+      }else {
+        // 详情页面中已经选择 服务项目 此时直接 跳转到 订单页面
+        // 跳转到 订单确认页面
+        gotoServiceOrderConfirmPage();
+      }
+    }else if(cleanType == servicesConstants.servicesType['airConditioner']!['code']){
       // 空调清洁
       // 弹出选择 空调型号和数量的弹框
       handlerShowChooseAirConditionerDialog(context);
-    }else if(detailServiceTypeCode == servicesConstants.servicesType['repaire']!['code']){
+    }else if(cleanType == servicesConstants.servicesType['repaire']!['code']){
       // 维修
     }
   }
@@ -292,7 +276,7 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
   // 显示选择 房屋清洁的弹框
   handlerShowChooseCleanConditionerDialog(BuildContext context) async{
     // 定时器
-    LoadState dialogState = LoadState.State_Loading;
+    LoadState dialogState = LoadState.State_Success;
     DialogEngine.show(
         tag: "chooseHouseClean",
         position: DialogPosition.bottom,
@@ -333,11 +317,12 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
           },
         )
     );
-
-    await Future.delayed(Duration(milliseconds: 1000));
-
-    _chooseHouseCleanDialogGlobalKey.currentState?.changeDialogLoadingState(LoadState.State_Success);    
   }
+  // 改变 _chooseHouseCleanDialogGlobalKey 的Loading状态
+  changeHouseCleanDialogLoadingState(LoadState state){
+    _chooseHouseCleanDialogGlobalKey.currentState?.changeDialogLoadingState(LoadState.State_Success);
+  }
+
   // 显示 选择空调型号和数量的弹框
   handlerShowChooseAirConditionerDialog(BuildContext context, ) async{
     // 定时器
@@ -348,7 +333,7 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
       widget: DialogContentWrap(
         key: _chooseAirCleanDialogGlobalKey,
         loadingState: dialogState,
-        maxHeight: 315.5,
+        maxHeight: 450.0,
         dialogWidth: context.screenSize.width,
         isShowConfirmBtn: true,
         isShowCancelBtn: false,
@@ -372,6 +357,7 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
         //   fontSize: 17,
         //   fontWeight: FontWeight.w400
         // ),
+        isConfirmAutoClose: false,
         confirmAction: chooseAirConditionConfirmFn,
         cancelAction: chooseAirConditionCancelFn,
         titleBuilder: (context) {
@@ -392,8 +378,13 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
     Log.d("点击了确定");
     DialogEngine.dismiss(tag: "chooseHouseClean");
     // 跳转到 订单确认页面
-    // appRouter.push(ServiceOrderConfirmPageRoute(id: _detailId, serviceTypeCode: _detailServiceTypeCode));
-    ServiceOrderConfirmPage.startInstance(id: _detailId, serviceTypeCode: _detailServiceTypeCode);
+    gotoServiceOrderConfirmPage();
+  }
+
+  // 去订单确认页面
+  gotoServiceOrderConfirmPage(){
+    // appRouter.push(ServiceOrderConfirmPageRoute(id: _detailId, cleanServiceType: _cleanServiceType));
+    ServiceOrderConfirmPage.startInstance(id: _detailId!, cleanServiceType: _cleanServiceType!);
   }
 
   chooseHouseCleanCancelFn(){
@@ -404,10 +395,16 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
 
   chooseAirConditionConfirmFn(){
     Log.d("点击了确定");
-    DialogEngine.dismiss(tag: "chooseAirConditionClean");
-    // 跳转到 订单确认页面
-    // appRouter.push(ServiceOrderConfirmPageRoute(id: _detailId, serviceTypeCode: _detailServiceTypeCode));
-    ServiceOrderConfirmPage.startInstance(id: _detailId, serviceTypeCode: _detailServiceTypeCode);
+    final chooseAirCleanContentVm= ref.watch(chooseAirConditionContentVmProvider.notifier);
+    if(chooseAirCleanContentVm?.state.hasCheckdService??false){
+      // 跳转到 订单确认页面
+      // appRouter.push(ServiceOrderConfirmPageRoute(id: _detailId, cleanServiceType: _cleanServiceType));
+      ServiceOrderConfirmPage.startInstance(id: _detailId!, cleanServiceType: _cleanServiceType!);
+      DialogEngine.dismiss(tag: "chooseAirConditionClean");
+    }else {
+      // 一个数量也没选 则英文提示
+      ToastEngine.show("Please Select Service");
+    }
   }
 
   chooseAirConditionCancelFn(){
@@ -416,23 +413,24 @@ class ServiceCleanDetailVm extends _$ServiceCleanDetailVm {
 
   
   Widget buildChooseHouseCleanTitle(BuildContext context){
-    return ChooseHouseCleanTitle(id: 0, serviceTypeCode: 0);
+    return ChooseHouseCleanTitle(id: _detailId!, cleanServiceType: _cleanServiceType!);
   }
 
   Widget buildChooseHouseCleanContent(BuildContext context){
-    return ChooseHouseCleanContent(id: 0, serviceTypeCode: 0,);
+    Log.d("打开弹框 products: ${state.datas!.products!}");
+    return ChooseHouseCleanContent(id: _detailId!, cleanServiceType: _cleanServiceType!, products: state.datas!.products!,);
   }
 
   Widget buildChooseAirConditionTitle(BuildContext context){
-    return ChooseAirConditionTitle(id: 0, serviceTypeCode: 0);
+    return ChooseAirConditionTitle(id: _detailId!, cleanServiceType: _cleanServiceType!);
   }
   
   Widget buildChooseAirConditionContent(BuildContext context){
-    return ChooseAirConditionContent(id: 0, serviceTypeCode: 0,);
+    return ChooseAirConditionContent(id: _detailId!, cleanServiceType: _cleanServiceType!,products: state.datas!.products!);
   }
 
   // 去 评价列表页面
-  gotoUserReviewsPage(BuildContext context, int id, int serviceTypeCode){
-    ServiceEvaluateListPage.startInstance(id:id, serviceTypeCode: serviceTypeCode);
+  gotoUserReviewsPage(BuildContext context, int id, String cleanServiceType){
+    ServiceEvaluateListPage.startInstance(id:id, cleanServiceType: cleanServiceType);
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/service_clean_detail/service_clean_detail_vm.g.dart

@@ -7,7 +7,7 @@ part of 'service_clean_detail_vm.dart';
 // **************************************************************************
 
 String _$serviceCleanDetailVmHash() =>
-    r'77e8421e0ac469ea7f2131499d6c15634efb6faa';
+    r'5ff571fb878b262e14b77aaf7a2046adc226ef51';
 
 /// See also [ServiceCleanDetailVm].
 @ProviderFor(ServiceCleanDetailVm)

+ 5 - 5
packages/cpt_services/lib/modules/services/service_evaluate_create/service_evaluate_create_page.dart

@@ -31,19 +31,19 @@ import 'service_evaluate_create_vm.dart';
 @RoutePage()
 class ServiceEvaluateCreatePage extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
   const ServiceEvaluateCreatePage({
     Key? key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   }) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required int id, required int serviceTypeCode}) {
+  static void startInstance({BuildContext? context, required int id, required String cleanServiceType}) {
     if (context != null) {
-      context.router.push(ServiceEvaluateCreatePageRoute(id: id, serviceTypeCode: serviceTypeCode));
+      context.router.push(ServiceEvaluateCreatePageRoute(id: id, cleanServiceType: cleanServiceType));
     } else {
-      appRouter.push(ServiceEvaluateCreatePageRoute(id:id, serviceTypeCode: serviceTypeCode));
+      appRouter.push(ServiceEvaluateCreatePageRoute(id:id, cleanServiceType: cleanServiceType));
     }
   }
 

+ 1 - 1
packages/cpt_services/lib/modules/services/service_evaluate_create/service_evaluate_create_vm.g.dart

@@ -7,7 +7,7 @@ part of 'service_evaluate_create_vm.dart';
 // **************************************************************************
 
 String _$serviceEvaluateCreateVmHash() =>
-    r'e3dcc7851836ad14ed970e2f4d5cc0482c71efcb';
+    r'4076871c4476ccd72aa607ef8e83e3925d25a789';
 
 /// See also [ServiceEvaluateCreateVm].
 @ProviderFor(ServiceEvaluateCreateVm)

+ 6 - 7
packages/cpt_services/lib/modules/services/service_evaluate_list/service_evaluate_list_page.dart

@@ -1,5 +1,4 @@
-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';
@@ -29,19 +28,19 @@ import '../../../components/status_card_item.dart';
 @RoutePage()
 class ServiceEvaluateListPage extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
   const ServiceEvaluateListPage({
     Key? key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   }) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required int id, required int serviceTypeCode}) {
+  static void startInstance({BuildContext? context, required int id, required String cleanServiceType}) {
     if (context != null) {
-      context.router.push( ServiceEvaluateListPageRoute(id:id, serviceTypeCode:serviceTypeCode));
+      context.router.push( ServiceEvaluateListPageRoute(id:id, cleanServiceType:cleanServiceType));
     } else {
-      appRouter.push(ServiceEvaluateListPageRoute(id:id, serviceTypeCode:serviceTypeCode));
+      appRouter.push(ServiceEvaluateListPageRoute(id:id, cleanServiceType:cleanServiceType));
     }
   }
 

+ 1 - 1
packages/cpt_services/lib/modules/services/service_evaluate_list/service_evaluate_list_vm.g.dart

@@ -7,7 +7,7 @@ part of 'service_evaluate_list_vm.dart';
 // **************************************************************************
 
 String _$serviceEvaluateListVmHash() =>
-    r'993c979ca4e734163a320a8369185748208344b6';
+    r'ca4e3fa5efaf52a15ee7505769b887eba5f465b4';
 
 /// See also [ServiceEvaluateListVm].
 @ProviderFor(ServiceEvaluateListVm)

+ 187 - 99
packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_page.dart

@@ -1,14 +1,19 @@
 import 'package:cpt_services/components/chooseAirConditionContent.dart';
 import 'package:cpt_services/components/chooseAirConditionContent_vm.dart';
+import 'package:cpt_services/components/chooseHouseCleanContent_vm.dart';
+import 'package:cpt_services/modules/services/service_clean_detail/service_clean_detail_vm.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
+import 'package:domain/entity/user_me_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:plugin_basic/provider/user_config/user_config_service.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/color_utils.dart';
@@ -24,7 +29,9 @@ import 'package:widgets/my_appbar.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../../../components/chooseAirConditionContent_state.dart';
 import '../../../components/chooseHouseCleanContent.dart';
+import '../../../components/chooseHouseCleanContent_state.dart';
 import '../../../components/chooseVisitTimeContent_vm.dart';
 import '../../../constants_services.dart';
 import '../../../router/page/services_page_router.dart';
@@ -35,19 +42,19 @@ import '../../../components/status_card_item.dart';
 @RoutePage()
 class ServiceOrderConfirmPage extends HookConsumerWidget {
   final int id;
-  final int serviceTypeCode;
+  final String cleanServiceType;
   const ServiceOrderConfirmPage({
     Key? key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   }) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required int id, required int serviceTypeCode}) {
+  static void startInstance({BuildContext? context, required int id, required String cleanServiceType}) {
     if (context != null) {
-      context.router.push(ServiceOrderConfirmPageRoute(id: id, serviceTypeCode: serviceTypeCode));
+      context.router.push(ServiceOrderConfirmPageRoute(id: id, cleanServiceType: cleanServiceType));
     } else {
-      appRouter.push(ServiceOrderConfirmPageRoute(id:id, serviceTypeCode: serviceTypeCode));
+      appRouter.push(ServiceOrderConfirmPageRoute(id:id, cleanServiceType: cleanServiceType));
     }
   }
 
@@ -58,12 +65,10 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
     final state = ref.watch(serviceOrderConfirmVmProvider);
     // final appConfigState = ref.watch(appConfigServiceProvider)
 
-    final totalPrice = ref.watch(serviceOrderConfirmVmProvider.select((state) => state.totalPrice));
-
     useEffect(() {
-      vm.setInitPageData(id: id, serviceTypeCode: serviceTypeCode);
+      vm.setInitPageData(id: id, cleanServiceType: cleanServiceType);
       // 组件挂载时执行 - 执行接口请求
-      Future.microtask(() => vm.initPageData());
+      Future.microtask(() => vm.initPageData(context));
       return () {
         // 组件卸载时执行
       };
@@ -98,7 +103,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                     // 底部联系信息
                     Visibility(
                       visible: state.loadingState == LoadState.State_Success,
-                      child: state.datas !=null ? _buildBottomSection(state, vm,ref, context, id, serviceTypeCode, totalPrice): Container(),
+                      child: state.datas !=null ? _buildBottomSection(state, vm,ref, context, id, cleanServiceType): Container(),
                     )
 
                   ],
@@ -128,7 +133,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             width: double.infinity,
             margin: const EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
             padding: const EdgeInsets.only(left: 10, right: 10, top: 18.5, bottom: 18.5),
-            child: _buildOrderProfile(state, vm, context),
+            child: _buildOrderProfile(state, vm, context, ref),
           ),
           // 订单 服务项目
           Container(
@@ -136,7 +141,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             width: double.infinity,
             margin: const EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
             padding: const EdgeInsets.only(left: 10, right: 10, top: 18.5, bottom: 18.5),
-            child: _buildOrderService(state, vm, context),
+            child: _buildOrderService(state, vm, context, ref),
           ),
           // 订单 上门时间
           Container(
@@ -144,7 +149,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             width: double.infinity,
             margin: const EdgeInsets.only(left: 0, right: 0, top: 5, bottom: 0),
             padding: const EdgeInsets.only(left: 10, right: 10, top: 18.5, bottom: 18.5),
-            child: _buildOrderVisitTime(state, vm, context).onTap((){
+            child: _buildOrderVisitTime(state, vm, context, ref).onTap((){
               vm.handlerClickVisitTime(context);
             }),
           ),
@@ -179,7 +184,10 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
   }
 
   Widget _buildOrderScore(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context) {
-    double score = 5.0;
+    PaidServiceDetailEntity? detailInfo = state.datas??null;
+    final String title = detailInfo?.name??'';
+    double evaluationsAvgScore = (detailInfo?.evaluationsAvgScore?? 5.0).toDouble();
+    final String merchantName = detailInfo?.merchant?.name??'';
     //  评分
     return Column(
       children: [
@@ -190,7 +198,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               MyTextView(
-                "House Cleaning Services",
+                "$title",
                 textColor: context.appColors.textBlack,
                 fontSize: 18,
                 isFontBold: true,
@@ -201,7 +209,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                 crossAxisAlignment: CrossAxisAlignment.center,
                 children: [
                   AnimatedRatingStars(
-                    initialRating: score,
+                    initialRating: evaluationsAvgScore,
                     onChanged: (rating) {
                     },
                     readOnly: true,
@@ -216,7 +224,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                     animationCurve: Curves.easeInOut,
                   ),
                   MyTextView(
-                    "${score}",
+                    "${evaluationsAvgScore}",
                     textColor: context.appColors.textBlack,
                     fontSize: 16,
                     isFontMedium: true,
@@ -225,7 +233,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                 ],
               ),
               MyTextView(
-                "HONG YE GROUP PTE LTD",
+                "$merchantName",
                 textColor: context.appColors.textDarkGray999,
                 fontSize: 12,
                 isFontRegular: true,
@@ -239,7 +247,12 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildOrderProfile(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context) {
+  Widget _buildOrderProfile(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context, WidgetRef ref) {
+    final userInfoState = UserConfigService.getState(ref: ref);
+    UserMeEntity? user = userInfoState.user;
+    String userUnit = user?.defaultUnit?.unit??'';
+    String userName = '${user?.information?.firstName??''}${user?.information?.lastName??''}';
+    String userPhone = '${user?.information?.phone}'??'';
     return Column(
       children: [
         Row(
@@ -258,7 +271,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 MyTextView(
-                  '705 Qiming Huijin Building',
+                  '$userUnit',
                   fontSize: 17,
                   isFontBold: true,
                   textColor: context.appColors.textBlack,
@@ -268,13 +281,13 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                   mainAxisAlignment: MainAxisAlignment.start,
                   children: [
                     MyTextView(
-                      'Sundy',
+                      '$userName',
                       fontSize: 14,
                       textColor: context.appColors.textDarkGray999,
                       isFontRegular: true,
                     ),
                     MyTextView(
-                      '+6588991122',
+                      '$userPhone',
                       fontSize: 14,
                       textColor: context.appColors.textDarkGray999,
                       isFontRegular: true,
@@ -290,7 +303,11 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
     );
   }
 
-  Widget _buildOrderService(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context) {
+  Widget _buildOrderService(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context, WidgetRef ref) {
+    final result = vm.getCurrentService();
+    List<HouseCleanContentItem> houseCleanCheckedServiceList = result["houseCleanCheckedServiceList"] as List<HouseCleanContentItem>;
+    List<AirConditionContentItem> airCleancheckedServiceList = result["airCleancheckedServiceList"] as List<AirConditionContentItem>;
+
     return Column(
       children: [
         Row(
@@ -314,93 +331,163 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             ),
           ],
         ),
-        if (serviceTypeCode == servicesConstants.servicesType['houseCleaning']!['code'])
-          // 室内清理
-          _buildCleanContent(state, vm, context)
-        else if (serviceTypeCode == servicesConstants.servicesType['airConditioner']!['code'])
-          // 空调清理
-          _buildCleanContent(state, vm, context)
+        if (cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code'])
+        // 室内清理
+          _buildHouseCleanContent(state, vm, context, ref, houseCleanCheckedServiceList)
+        else if (cleanServiceType == servicesConstants.servicesType['airConditioner']!['code'])
+        // 空调清理
+          _buildAirCleanCleanContent(state, vm, context, ref, airCleancheckedServiceList)
         else
           const SizedBox.shrink(),
       ],
     );
   }
 
-  Widget _buildCleanContent(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context) {
-    final title = 'House Cleaning Services';
-    final areaSizeRange = '1 Bedroom';
-    final num =  1;
-    final price = 0;
-    bool isChecked = false;
-    bool disabled = true;
-    final isDisable = useState<bool>(disabled);
-
-    return Container(
-      padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
-      margin: EdgeInsets.only(left: 15, right: 15, top: 0, bottom: 0),
-      color: ColorUtils.string2Color('#F8F8F8'),
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            mainAxisSize: MainAxisSize.max,
-            children: [
-              Expanded(
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
+  Widget _buildHouseCleanContent(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context, WidgetRef ref, List<HouseCleanContentItem> checkedServiceList) {
+    if(checkedServiceList.isNotEmpty){
+      return Column(
+        children: List.generate(checkedServiceList.length, (index){
+          HouseCleanContentItem currentItem = checkedServiceList[index] as HouseCleanContentItem;
+          final title = currentItem.name??'';
+          final areaSizeRange = currentItem.areaSizeRange??'';
+          final num = currentItem.num?? 1;
+          final price = currentItem.price?? 0;
+          return  Container(
+            padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
+            margin: const EdgeInsets.only(left: 15, right: 15, top: 0, bottom: 0),
+            color: ColorUtils.string2Color('#F8F8F8'),
+            child: Column(
+              children: [
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  mainAxisSize: MainAxisSize.max,
                   children: [
-                    MyTextView(
-                      title,
-                      fontSize: 16,
-                      isFontMedium: true,
-                      textColor: context.appColors.textBlack,
+                    Expanded(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          MyTextView(
+                            title,
+                            fontSize: 16,
+                            isFontMedium: true,
+                            textColor: context.appColors.textBlack,
+                          ),
+                          MyTextView(
+                            areaSizeRange,
+                            fontSize: 15,
+                            isFontRegular: true,
+                            textColor: context.appColors.textDarkGray999,
+                            marginTop: 5,
+                          ),
+                        ],
+                      ),
                     ),
-                    MyTextView(
-                      areaSizeRange,
-                      fontSize: 15,
-                      isFontRegular: true,
-                      textColor: context.appColors.textDarkGray999,
-                      marginTop: 5,
+                    // MyCartNum(onChange: (value){
+                    //   vm.handlerChangeNum(context, value, index);
+                    // })
+                    // MyButton(
+                    //   text: '\$$price',
+                    //   onPressed: (){
+                    //       // vm.handlerChangeNum(context, value, index);
+                    //   },
+                    //   fontSize: 19,
+                    //   fontWeight: FontWeight.w500,
+                    // )
+                    Container(
+                      child: MyButton(
+                        text: '\$$price',
+                        onPressed: null,
+                        minWidth: 80,
+                        minHeight: 40,
+                        fontSize: 19,
+                        fontWeight: FontWeight.w500,
+                        // enable: !isDisable.value,
+                        textColor:  context.appColors.textPrimary,
+                        backgroundColor: context.appColors.textWhite,
+                        disabledBackgroundColor: context.appColors.disEnableGray,
+                        disabledTextColor: context.appColors.textWhite,
+                      ),
                     ),
                   ],
                 ),
-              ),
-              // MyCartNum(onChange: (value){
-              //   vm.handlerChangeNum(context, value, index);
-              // })
-              // MyButton(
-              //   text: '\$$price',
-              //   onPressed: (){
-              //       // vm.handlerChangeNum(context, value, index);
-              //   },
-              //   fontSize: 19,
-              //   fontWeight: FontWeight.w500,
-              // )
-              Container(
-                child: MyButton(
-                  text: '\$$price',
-                  onPressed: null,
-                  minWidth: 80,
-                  minHeight: 40,
-                  fontSize: 19,
-                  fontWeight: FontWeight.w500,
-                  // enable: !isDisable.value,
-                  textColor:  context.appColors.textPrimary,
-                  backgroundColor: context.appColors.textWhite,
-                  disabledBackgroundColor: context.appColors.disEnableGray,
-                  disabledTextColor: context.appColors.textWhite,
+                // Divider(),
+              ],
+            ),
+          );
+        }),
+      );
+    }else {
+      return const SizedBox.shrink();
+    }
+  }
+
+  Widget _buildAirCleanCleanContent(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context, WidgetRef ref, List<AirConditionContentItem> checkedServiceList) {
+    if(checkedServiceList.isNotEmpty){
+      return Column(
+        children: List.generate(checkedServiceList.length, (index){
+          AirConditionContentItem currentItem = checkedServiceList[index] as AirConditionContentItem;
+          final title = currentItem.name??'';
+          final num = currentItem.num?? 1;
+          final price = currentItem.price?? 0;
+          return  Container(
+            padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
+            margin: const EdgeInsets.only(left: 15, right: 15, top: 0, bottom: 0),
+            color: ColorUtils.string2Color('#F8F8F8'),
+            child: Column(
+              children: [
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  mainAxisSize: MainAxisSize.max,
+                  children: [
+                    Expanded(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          MyTextView(
+                            title,
+                            fontSize: 16,
+                            isFontMedium: true,
+                            textColor: context.appColors.textBlack,
+                          ),
+                          MyTextView(
+                            'X $num',
+                            fontSize: 15,
+                            isFontRegular: true,
+                            textColor: context.appColors.textDarkGray999,
+                            marginTop: 5,
+                          ),
+                        ],
+                      ),
+                    ),
+                    MyButton(
+                      text: '\$$price',
+                      onPressed: null,
+                      minWidth: 80,
+                      minHeight: 40,
+                      fontSize: 19,
+                      fontWeight: FontWeight.w500,
+                      // enable: !isDisable.value,
+                      textColor:  context.appColors.textPrimary,
+                      backgroundColor: context.appColors.textWhite,
+                      disabledBackgroundColor: context.appColors.disEnableGray,
+                      disabledTextColor: context.appColors.textWhite,
+                    ),
+                  ],
                 ),
-              ),
-            ],
-          ),
-          // Divider(),
-        ],
-      ),
-    );
+                // Divider(),
+              ],
+            ),
+          );
+        }),
+      );
+    }else {
+      return const SizedBox.shrink();
+    }
   }
 
 
-  Widget _buildOrderVisitTime(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context) {
+  Widget _buildOrderVisitTime(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm, BuildContext context, WidgetRef ref) {
+    String visitTime = state.visitTime??'';
     return Row(
       mainAxisSize: MainAxisSize.max,
       mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -429,7 +516,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
             mainAxisAlignment: MainAxisAlignment.end,
             children: [
               MyTextView(
-                '2021-01-01 12:00',
+                '$visitTime',
                 fontSize: 15,
                 textColor: context.appColors.textDarkGray999,
                 isFontRegular: true,
@@ -643,7 +730,8 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
   }
 
   // 底部操作区域
-  Widget _buildBottomSection(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm,WidgetRef ref, BuildContext context, int id, int serviceTypeCode, totalPrice) {
+  Widget _buildBottomSection(ServiceOrderConfirmState state, ServiceOrderConfirmVm vm,WidgetRef ref, BuildContext context, int id, String cleanServiceType) {
+    double toTalPrice = ref.watch(serviceOrderConfirmVmProvider.select((state) => state.totalPrice??0.0));
     return Container(
       height: 50,
       width: double.infinity,
@@ -666,7 +754,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                     mainAxisSize: MainAxisSize.max,
                     children: [
                       MyTextView(
-                        "\$$totalPrice",
+                        "\$$toTalPrice",
                         fontSize: 18,
                         textColor: Colors.white,
                         isFontRegular: true,
@@ -695,7 +783,7 @@ class ServiceOrderConfirmPage extends HookConsumerWidget {
                 ),
               ),
             ).onTap((){
-              vm.handlerClickPayNow(context, id: id , serviceTypeCode: serviceTypeCode);
+              vm.handlerClickPayNow(context, id: id , cleanServiceType: cleanServiceType);
             }),
           ),
         ],

+ 13 - 3
packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_state.dart

@@ -1,3 +1,5 @@
+import 'package:domain/entity/paid_service_detail_entity.dart';
+import 'package:domain/entity/paid_service_pay_success_info_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:widgets/load_state_layout.dart';
 
@@ -6,17 +8,22 @@ class ServiceOrderConfirmState {
   LoadState loadingState;
   String? errorMessage;
   double? totalPrice;
+  String? visitTime;
   Map<String, Map<String, dynamic>> remarkInfo;
-  Map<String, dynamic>? datas;
+  PaidServiceDetailEntity? datas;
+
+  // 成功支付后的数据
+  PaidServicePaySuccessInfoEntity? paidServicePaySuccessInfo;
 
 
   ServiceOrderConfirmState({
     this.loadingState = LoadState.State_Loading,
     String? errorMessage,
     double? totalPrice,
-
+    this.visitTime,
     remarkInfo,
     this.datas,
+    this.paidServicePaySuccessInfo,
   }): remarkInfo = remarkInfo ?? {
     "remark": {
       'value': '',
@@ -32,13 +39,16 @@ class ServiceOrderConfirmState {
     LoadState? loadingState,
     String? errorMessage,
     double? totalPrice,
+    String? visitTime,
     Map<String, dynamic>? remarkInfo,
-    Map<String, dynamic>? datas,
+    PaidServiceDetailEntity? datas,
+    PaidServicePaySuccessInfoEntity? paidServicePaySuccessInfo,
   }) {
     return ServiceOrderConfirmState(
       loadingState: loadingState ?? this.loadingState,
       errorMessage: errorMessage ?? this.errorMessage,
       totalPrice: totalPrice ?? this.totalPrice,
+      visitTime: visitTime ?? this.visitTime,
       remarkInfo: remarkInfo ?? this.remarkInfo,
       datas: datas ?? this.datas,
     );

+ 187 - 129
packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_vm.dart

@@ -8,6 +8,8 @@ import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/newsfeed_detail_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
+import 'package:domain/entity/paid_service_pay_success_info_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
@@ -20,12 +22,15 @@ import 'package:widgets/dialog/dialog_content_wrap.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../../../components/chooseAirConditionContent_state.dart';
 import '../../../components/chooseHouseCleanContent.dart';
+import '../../../components/chooseHouseCleanContent_state.dart';
 import '../../../components/chooseHouseCleanTitle.dart';
 import '../../../components/chooseVisitTimeBottomFooter.dart';
 import '../../../constants_services.dart';
 import '../../../respository/services_respository.dart';
 import '../../../router/page/services_page_router.dart';
+import '../service_clean_detail/service_clean_detail_vm.dart';
 import '../service_pay_success/service_pay_success_page.dart';
 import 'service_order_confirm_state.dart';
 
@@ -42,8 +47,8 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
   int _limit = 10; // 每页数量
   int _count = 0; // 总条数
 
-  int _detailId = 0;
-  int _detailServiceTypeCode = 0;
+  int? _id;
+  String? _cleanServiceType;
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
@@ -51,17 +56,21 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
     controlFinishLoad: true,   //允许加载
   );
 
-  ServiceOrderConfirmState initState() {
+
+
+  ServiceOrderConfirmState initState(PaidServiceDetailEntity detailEntity) {
     return ServiceOrderConfirmState(
-      datas: {}
+      datas: detailEntity
     );
   }
 
   @override
   ServiceOrderConfirmState build(){
     // 引入数据仓库
-    // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
-    final state = initState();
+    servicesRespositoryInstance = ref.read(servicesRespositoryProvider);
+    final serviceDetailVm = ref.read(serviceCleanDetailVmProvider.notifier);
+    PaidServiceDetailEntity detailEntity = serviceDetailVm.state.datas!;
+    final state = initState(detailEntity);
     Log.d("--------------------------build---------------------");
 
     return state;
@@ -77,34 +86,32 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
   }
 
 
-  setInitPageData({required int id, required int serviceTypeCode}){
-    _detailId = id;
-    _detailServiceTypeCode = serviceTypeCode;
+  setInitPageData({required int id, required String cleanServiceType}){
+    _id = id;
+    _cleanServiceType = cleanServiceType;
   }
   // 初始化页面数据
-  initPageData({detailId, detailServiceTypeCode}) {
-    _detailId = detailId??_detailId;
-    _detailServiceTypeCode = detailServiceTypeCode??_detailServiceTypeCode;
+  initPageData(BuildContext context) {
     Log.d("--------------------------initPageData---------------------");
     changeLoadingState(LoadState.State_Success, null);
-    setConfirmOrderTotalPrice(null);
+
+    WidgetsBinding.instance.addPostFrameCallback((_){
+      // 设置/更新 totalPrice
+      setConfirmOrderTotalPrice(context);
+    });
   }
 
   // 上拉加载 更多
   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();
   }
 
 
@@ -123,7 +130,6 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
     refreshController.resetFooter();
     _page = 1;
     _needShowPlaceholder = true;
-    getListData();
   }
 
 
@@ -131,89 +137,9 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
   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 维修
-        'cover_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',
-        'duration': 'Daily cleaning for 2 hours',
-        'totalPrice': 66,
-        'visit_time': '14 0ct 2024 15:00',
-        'order_time': '13 0ct 2024 12:00',
-        'status_text': 'In Progress',
-        'status_code': 0,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':2,
-        'service_type': 0,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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',
-        'duration': 'Daily cleaning for 2 hours',
-        'totalPrice': 66,
-        'visit_time': '14 0ct 2024 15:00',
-        'order_time': '13 0ct 2024 12:00',
-        'status_text': 'In Progress',
-        'status_code': 1,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-      {
-        'id':3,
-        'service_type': 0,  // 0 房屋保洁 1 空调保洁  2 维修
-        'cover_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',
-        'duration': 'Daily cleaning for 2 hours',
-        'totalPrice': 66,
-        'visit_time': '14 0ct 2024 15:00',
-        'order_time': '13 0ct 2024 12:00',
-        'status_text': 'In Progress',
-        'status_code': 1,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-    ];
-    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) {
@@ -261,24 +187,22 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
     });
   }
 
-
+  // 点击预约时间
   handlerClickVisitTime(BuildContext context){
-    // ToastEngine.show("Visit Time");
     handlerShowChooseVisitTimeDialog(context);
   }
 
-  // 显示 选择空调型号和数量的弹框
+  // 显示 预约时间弹框
   handlerShowChooseVisitTimeDialog(BuildContext context) async{
     // 定时器
-    LoadState dialogState = LoadState.State_Loading;
-
+    LoadState dialogState = LoadState.State_Success;
     DialogEngine.show(
-        tag: "chooseAirConditionClean",
+        tag: "chooseVisitTimeDialog",
         position: DialogPosition.bottom,
         widget: DialogContentWrap(
           key: _chooseVisitTimeDialogGlobalKey,
           loadingState: dialogState,
-          maxHeight: 480.0,
+          maxHeight: 450.0,
           dialogWidth: context.screenSize.width,
           isShowConfirmBtn: false,
           isShowCancelBtn: false,
@@ -315,16 +239,17 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
           },
         )
     );
+  }
 
-    await Future.delayed(Duration(milliseconds: 1000));
-
+  // 修改 _chooseVisitTimeDialogGlobalKey 弹框的 loading状态
+  changeDialogLoadingState(LoadState state){
     _chooseVisitTimeDialogGlobalKey.currentState?.changeDialogLoadingState(LoadState.State_Success);
   }
 
   chooseVisitTimeConfirmFn(){
-    Log.d("点击了确定");
+    Log.d("预约时间 点击了确定");
     // 跳转到 订单确认页面
-    // appRouter.push(ServiceOrderConfirmPageRoute(id: _detailId, serviceTypeCode: _detailServiceTypeCode));
+    // appRouter.push(ServiceOrderConfirmPageRoute(id: _id, cleanServiceType: _cleanServiceType));
   }
 
   chooseVisitTimeCancelFn(){
@@ -332,43 +257,176 @@ class ServiceOrderConfirmVm extends _$ServiceOrderConfirmVm {
   }
 
   Widget buildChooseVisitTimeTitle(BuildContext context){
-    return ChooseVisitTimeTitle(id: 0, serviceTypeCode: 0);
+    return ChooseVisitTimeTitle(id: 0, cleanServiceType: _cleanServiceType!);
   }
 
   Widget buildChooseVisitTimeContent(BuildContext context){
-    return ChooseVisitTimeContent(id: 0, serviceTypeCode: 0,);
+    return ChooseVisitTimeContent(id: _id!, cleanServiceType: _cleanServiceType!,);
   }
 
   Widget buildChooseVisitTimeBottomFooter(BuildContext context){
-    return ChooseVisitTimeBottomFooter(id: 0, serviceTypeCode: 0,);
+    return ChooseVisitTimeBottomFooter(id: _id!, cleanServiceType: _cleanServiceType!,);
+  }
+
+  // 更新visitTime
+  handlerUpdateVisitTime(String visitTime){
+    Log.d("选择的visitTime: $visitTime");
+    state = state.copyWith(visitTime: visitTime);
   }
 
   // 关闭visitTime 选择的弹框
   handlerHideVisitTimeDialog(){
-    DialogEngine.dismiss(tag: 'chooseAirConditionClean');
+    DialogEngine.dismiss(tag: 'chooseVisitTimeDialog');
+  }
+
+  // 获取 当前 所选的服务
+  Map<String, dynamic> getCurrentService(){
+    final chooseHouseCleanServiceDetailVm = ref.watch(chooseHouseCleanContentVmProvider.notifier);
+    List<HouseCleanContentItem> houseCleanCheckedServiceList = [];
+    final chooseAirCleanServiceDetailVm = ref.watch(chooseAirConditionContentVmProvider.notifier);
+    List<AirConditionContentItem> airCleancheckedServiceList = [];
+
+    if (_cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code']) {
+      houseCleanCheckedServiceList = chooseHouseCleanServiceDetailVm.state.checkedServiceList ?? [];
+    } else if (_cleanServiceType == servicesConstants.servicesType['airConditioner']!['code']) {
+      airCleancheckedServiceList = chooseAirCleanServiceDetailVm.state.checkedServiceList ?? [];
+    }
+
+    return {
+      "houseCleanCheckedServiceList": houseCleanCheckedServiceList,
+      "airCleancheckedServiceList": airCleancheckedServiceList
+    };
   }
 
   // 去支付
-  handlerClickPayNow(BuildContext context, {int? id, int? serviceTypeCode}){
-    ToastEngine.show("Pay Now");
-    // 去支付成功页面
-    ServicePaySuccessPage.startInstance(id: 0, serviceTypeCode: 0);
+  handlerClickPayNow(BuildContext context, {int? id, String? cleanServiceType}) async{
+    // ToastEngine.show("Pay Now");
+    if(state.visitTime == null || state.visitTime!.isEmpty){
+      // 预约时间没有
+      ToastEngine.show("Please select the visit time");
+      return;
+    }
+    try {
+      Map<String, dynamic> params = {
+        "planned_service_at": state.visitTime,
+        "notes": getRemarkInfo(),
+      };
+      // params 添加 product 参数
+      Map<String, dynamic> resultParams = handlerSubmitParams();
+      // 数组参数扁平
+      List<Map<String, dynamic>> products = resultParams['products'].cast<Map<String, dynamic>>();
+      String productsKey = 'products';
+      List<String> keys = ['id', 'quantity'];
+
+      Map<String, dynamic> flattenedProducts = handlerFlattenArrayParams(products, productsKey, keys);
+      // 合并参数
+      params.addAll(flattenedProducts);
+      Log.d("最终的参数params:  $params");
+
+      // final result = await servicesRespositoryInstance.fetchPaidServiceBook(params);
+      // if(result.isSuccess){
+      //   state = state.copyWith(paidServicePaySuccessInfo: result.data as PaidServicePaySuccessInfoEntity);
+      //   // 成功后 去支付成功页面
+      //   // ServicePaySuccessPage.startInstance();
+      //   context.appRouter.pushAndPopUntil(const ServicePaySuccessPageRoute(), predicate: (Route<dynamic> route) {       // 根据具体条件返回 true 或 false
+      //     // Log.d("888 ${route.settings}");
+      //     return route.settings.name != 'ServiceOrderConfirmPageRoute';
+      //   });
+      // } else {
+      //   String errorMessage = result.errorMsg!;
+      //   // changeLoadingState(LoadState.State_Error, errorMessage);
+      //   ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      // }
+
+
+      context.appRouter.pushAndPopUntil(const ServicePaySuccessPageRoute(), predicate: (Route<dynamic> route) {       // 根据具体条件返回 true 或 false
+        // Log.d("888 ${route.settings}");
+        return route.settings.name != 'ServiceOrderConfirmPageRoute';
+      });
+
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+
   }
 
+  Map<String, dynamic> handlerFlattenArrayParams(List<Map<String, dynamic>> products, String productsKey, List<String> keys) {
+    Map<String, dynamic> flattened = {};
+    for (int i = 0; i < products.length; i++) {
+      for (String key in keys) {
+        if (products[i].containsKey(key)) {
+          flattened['$productsKey[$i][$key]'] = products[i][key];
+        }
+      }
+    }
+    return flattened;
+  }
+
+  Map<String, dynamic> handlerSubmitParams(){
+    Map<String, dynamic> resultParams = {};
+    final result = getCurrentService();
+    List<HouseCleanContentItem> houseCleanCheckedServiceList = result["houseCleanCheckedServiceList"] as List<HouseCleanContentItem>;
+    List<AirConditionContentItem> airCleancheckedServiceList = result["airCleancheckedServiceList"] as List<AirConditionContentItem>;
+
+    Log.d("houseCleanCheckedServiceList  $houseCleanCheckedServiceList");
+    Log.d("airCleancheckedServiceList  $airCleancheckedServiceList");
+    if(_cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code']){
+      if(houseCleanCheckedServiceList != null && houseCleanCheckedServiceList.length > 0){
+        resultParams['products'] = []; // 初始化 products 为一个 List
+        houseCleanCheckedServiceList.asMap().forEach((idx, element) {
+          resultParams['products'].add({
+            'id': element.id,
+            'quantity': element.num ?? 1,
+          });
+        });
+      }
+    }else if(_cleanServiceType == servicesConstants.servicesType['airConditioner']!['code']){
+      if(airCleancheckedServiceList != null && airCleancheckedServiceList.length > 0){
+        resultParams['products'] = []; // 初始化 products 为一个 List
+        airCleancheckedServiceList.asMap().forEach((idx, element) {
+          resultParams['products'].add({
+            'id': element.id,
+            'quantity': element.num ?? 1,
+          });
+        });
+      }
+    }
+    return resultParams;
+  }
+  // 获取订单备注
+  String getRemarkInfo(){
+    String remarkInfo = "";
+    if(state.remarkInfo != null){
+      remarkInfo = state.remarkInfo!["remark"]!['controller'].text;
+    }
+    Log.d("订单的备注信息: $remarkInfo");
+    return remarkInfo;
+  }
+  // 设置订单相关数据
   setConfirmOrderTotalPrice(BuildContext? context){
-    final visitTimeTotalPrice = ref.read(chooseVisitTimeContentVmProvider).totalPrice?? 0.0;
-    final airConditionTotalPrice = ref.read(chooseAirConditionContentVmProvider).totalPrice?? 0.0 ;
-    final houseCleaningTotalPrice = ref.read(chooseHouseCleanContentVmProvider).totalPrice?? 0.0;
-    final totalPrice = visitTimeTotalPrice.toDouble() + airConditionTotalPrice.toDouble() + houseCleaningTotalPrice.toDouble();
-    // if( _detailServiceTypeCode == servicesConstants.servicesType['houseCleaning'] ){
-    //
-    // }else if(_detailServiceTypeCode == servicesConstants.servicesType['airConditioner']){
-    //
-    // }else {
-    //
-    // }
+    Log.d("service_order_confirm_vm 设置订单页面的相关数据");
+    double cleanServiceToTalPrice = 0.0;
+    final chooseHouseCleanCotentVm = ref.read(chooseHouseCleanContentVmProvider.notifier);
+    double houseCleanTotalPrice = 0.0;
+    final chooseAirCleanContentVm = ref.read(chooseAirConditionContentVmProvider.notifier);
+    double airCleanTotalPrice = 0.0;
+
+    if (_cleanServiceType == servicesConstants.servicesType['houseCleaning']!['code']) {
+      houseCleanTotalPrice = (chooseHouseCleanCotentVm?.state.totalPrice ?? 0.0).toDouble();
+      cleanServiceToTalPrice = houseCleanTotalPrice;
+    } else if (_cleanServiceType == servicesConstants.servicesType['airConditioner']!['code']) {
+      airCleanTotalPrice = (chooseAirCleanContentVm?.state.totalPrice ?? 0.0).toDouble();
+      cleanServiceToTalPrice = airCleanTotalPrice;
+    }
+
+    final totalPrice = cleanServiceToTalPrice.toDouble();
+
+    final serviceDetailVm = ref.read(serviceCleanDetailVmProvider.notifier);
+
+
     state = state.copyWith(
-        totalPrice: totalPrice
+        totalPrice: totalPrice,
+        datas: serviceDetailVm?.state.datas!
     );
   }
 }

+ 1 - 1
packages/cpt_services/lib/modules/services/service_order_confirm/service_order_confirm_vm.g.dart

@@ -7,7 +7,7 @@ part of 'service_order_confirm_vm.dart';
 // **************************************************************************
 
 String _$serviceOrderConfirmVmHash() =>
-    r'f302671a6b33ca6b42dd89579c7a75e3b2356be6';
+    r'586ef070a06d954a4aed1735d642b1e8fb8c02da';
 
 /// See also [ServiceOrderConfirmVm].
 @ProviderFor(ServiceOrderConfirmVm)

+ 3 - 7
packages/cpt_services/lib/modules/services/service_pay_success/service_pay_success_page.dart

@@ -28,20 +28,16 @@ import '../../../components/status_card_item.dart';
 
 @RoutePage()
 class ServicePaySuccessPage extends HookConsumerWidget {
-  final int id;
-  final int serviceTypeCode;
   const ServicePaySuccessPage({
     Key? key,
-    required this.id,
-    required this.serviceTypeCode,
   }) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required int id, required int serviceTypeCode}) {
+  static void startInstance({BuildContext? context,}) {
     if (context != null) {
-      context.router.push(ServicePaySuccessPageRoute(id: id, serviceTypeCode: serviceTypeCode));
+      context.router.push(ServicePaySuccessPageRoute());
     } else {
-      appRouter.push(ServicePaySuccessPageRoute(id:id, serviceTypeCode: serviceTypeCode));
+      appRouter.push(ServicePaySuccessPageRoute());
     }
   }
 

+ 1 - 1
packages/cpt_services/lib/modules/services/service_repair_detail/service_repair_detail_vm.dart

@@ -289,7 +289,7 @@ class ServiceRepairDetailVm extends _$ServiceRepairDetailVm {
                     textAlign: TextAlign.center,
                     textColor: ColorUtils.string2Color("#4161D0"),
                   ),
-                  SizedBox(
+                  const SizedBox(
                     height: 20,
                   ),
                   MyTextView(

+ 1 - 1
packages/cpt_services/lib/modules/services/service_repair_detail/service_repair_detail_vm.g.dart

@@ -7,7 +7,7 @@ part of 'service_repair_detail_vm.dart';
 // **************************************************************************
 
 String _$serviceRepairDetailVmHash() =>
-    r'26e25c4041436aaefa8c3eb25a2921a7c3daeb7a';
+    r'9113465692ae1a7b14627b090fa06e7696f61ddf';
 
 /// See also [ServiceRepairDetailVm].
 @ProviderFor(ServiceRepairDetailVm)

+ 92 - 45
packages/cpt_services/lib/modules/services/services_main_page.dart

@@ -1,5 +1,7 @@
 
+import 'package:cpt_services/modules/services/services_main_vm.dart';
 import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/service_category_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/rendering.dart';
@@ -10,6 +12,7 @@ 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/custom_sliver_persistent_header_delegate.dart';
+import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_text_view.dart';
@@ -23,8 +26,8 @@ import 'repair/repair_page.dart';
 import 'services_page.dart';
 
 enum ServicesType {
-  cleaning,
-  repair,
+  paid,
+  inquiry,
 }
 
 
@@ -44,57 +47,108 @@ class ServicesMainPage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-
-    useEffect(() {
-      // 监听窗口
-    }, []);
-
+    final vm = ref.read(serviceMainVmProvider.notifier);
+    final state = ref.watch(serviceMainVmProvider);
 
     useEffect(() {
       Log.d("ServicesMainPage initState");
-      // 延迟监听
-
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => vm.initPageData());
+      return () {
+        Log.d("ServicesMainPage dispose");
+      };
     }, []);
 
     return Scaffold(
       appBar: MyAppBar.appBar(
         context,
-        "ServicesMain",
+        "Service",
         backgroundColor: context.appColors.whiteBG,
       ),
       backgroundColor: ColorUtils.string2Color("#F2F3F6"),
-      body: Container(
-        child: GridView.count(
-          crossAxisCount: 2,
-          padding: EdgeInsets.all(10),
-          mainAxisSpacing: 10,
-          crossAxisSpacing: 10,
-          childAspectRatio: 165/146,
-          children: [
-            _buildServiceCard(
-              context,
-              ServicesType.cleaning,
-              Assets.serviceHomeServices,
-              "Home Services",
-              102.5,
-              82.5,
-              ServicesPage.startInstance,
-            ),
-            _buildServiceCard(
-              context,
-              ServicesType.repair,
-              Assets.serviceMaintenance,
-              "Maintenance",
-              129,
-              107.5,
-              RepairPage.startInstance,
+      body: Column(
+        children: [
+          Expanded(
+            child: EasyRefresh(
+              controller: vm.refreshController,
+              // 上拉加载
+              onLoad: null,
+              // 下拉刷新
+              onRefresh: () async{
+                Log.d("----onRefresh");
+                vm.onRefresh();
+              },
+              child: LoadStateLayout(
+                state: state.loadingState!,
+                errorMessage: state.errorMessage,
+                errorRetry: () {
+                  vm.retryRequest();
+                },
+                successSliverWidget:[
+                  SliverGrid(
+                    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+                      crossAxisCount: 2,
+                      mainAxisSpacing: 10,
+                      crossAxisSpacing: 10,
+                      childAspectRatio: 165/146, //宽高比
+                    ),
+                    delegate: SliverChildBuilderDelegate(
+                          (context, index) {
+                        return  Padding(
+                          padding: const EdgeInsets.all(10.0),
+                          child: _buildCardItem(context, ref, state.datas?[index] as ServiceCategoryEntity, vm).onTap((){
+                            final data = state.datas?[index] as ServiceCategoryEntity;
+                            if (data.id != null && data.type != null) {
+                              vm.goToPaidOrRepairListPage(context, data.id!, data.type!, data);
+                            }
+                          }),
+                        );
+                      },
+                      childCount: state.datas?.length,
+                    ),
+                  ),
+                ]
+              ),
             ),
-          ]
-        ),
+          ),
+        ],
       ),
     );
   }
 
+  Widget _buildCardItem(BuildContext context, WidgetRef ref, ServiceCategoryEntity data, ServiceMainVm vm){
+    if(data?.id == 1){
+      // home Services
+      return _buildServiceCard(
+        context,
+        ServicesType.paid,
+        Assets.serviceHomeServices,
+        "Home Services",
+        102.5,
+        82.5
+      );
+    }else if(data?.id == 4){
+        // maintenance
+        return _buildServiceCard(
+          context,
+          ServicesType.inquiry,
+          Assets.serviceMaintenance,
+          "Maintenance",
+          129,
+          107.5
+        );
+    }else {
+      return _buildServiceCard(
+        context,
+        ServicesType.paid,
+        Assets.serviceHomeServices,
+        "Home Services",
+        102.5,
+        82.5
+      );
+    }
+  }
+
   Widget _buildServiceCard(
     BuildContext context,
     ServicesType type,
@@ -102,7 +156,6 @@ class ServicesMainPage extends HookConsumerWidget {
     String title,
       double iconWidth,
       double iconHeight,
-    Function() onTap,
   ) {
     return Container(
       margin: EdgeInsets.all(10),
@@ -142,13 +195,7 @@ class ServicesMainPage extends HookConsumerWidget {
           )
         ]
       )
-    ).onTap((){
-      if(type == ServicesType.cleaning){
-        ServicesPage.startInstance();
-      }else if(type == ServicesType.repair){
-        RepairPage.startInstance();
-      }
-    });
+    );
   }
 }
 

+ 35 - 0
packages/cpt_services/lib/modules/services/services_main_state.dart

@@ -0,0 +1,35 @@
+import 'package:domain/entity/service_category_entity.dart';
+import 'package:widgets/load_state_layout.dart';
+
+class ServiceMainState {
+  //页面 LoadView 状态的展示
+  LoadState? loadingState;
+  String? errorMessage;
+
+  // getter curId
+  int? get curId => curCategory?.id;
+  final ServiceCategoryEntity? curCategory;
+
+  List<ServiceCategoryEntity>? datas;
+
+  ServiceMainState({
+    this.loadingState = LoadState.State_Loading,
+    this.errorMessage,
+    this.curCategory,
+    this.datas,
+  });
+
+  ServiceMainState copyWith({
+    LoadState? loadingState,
+    String? errorMessage,
+    ServiceCategoryEntity? curCategory,
+    List<ServiceCategoryEntity>? datas,
+  }) {
+    return ServiceMainState(
+      loadingState: loadingState ?? this.loadingState,
+      errorMessage: errorMessage ?? this.errorMessage,
+      curCategory: curCategory ?? this.curCategory,
+      datas: datas ?? this.datas,
+    );
+  }
+}

+ 163 - 0
packages/cpt_services/lib/modules/services/services_main_vm.dart

@@ -0,0 +1,163 @@
+
+import 'dart:async';
+
+import 'package:cpt_services/modules/services/repair/repair_page.dart';
+import 'package:cpt_services/modules/services/services_page.dart';
+import 'package:domain/entity/service_category_entity.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/ext_dart.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:widgets/dialog/dialog_content_wrap.dart';
+import '../../../respository/services_respository.dart';
+import '../../../router/page/services_page_router.dart';
+import 'services_main_page.dart';
+import 'services_main_state.dart';
+
+part 'services_main_vm.g.dart';
+
+
+@riverpod
+class ServiceMainVm extends _$ServiceMainVm {
+  late ServicesRespository serviceRespositoryInstance;
+
+  int _detailId = 0;
+  int _detailServiceTypeCode = 0;
+
+  bool _needShowPlaceholder = true; //是否展示LoadingView
+
+  int _page = 1;  // 当前页
+  int _limit = 10; // 每页数量
+  int _count = 0; // 总条数
+
+  int _totalnum = 130;
+
+  int totalnum = 50;
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,  //允许刷新
+    controlFinishLoad: true,   //允许加载
+  );
+
+  ServiceMainState initState() {
+    return ServiceMainState(
+      datas: null,
+    );
+  }
+
+  @override
+  ServiceMainState build(){
+    // 引入数据仓库
+    serviceRespositoryInstance = ref.read(servicesRespositoryProvider);
+    final state = initState();
+    Log.d("--------------------------build---------------------");
+
+    return state;
+  }
+
+
+  //刷新页面状态
+  void changeLoadingState(LoadState loadState, String? errorMsg) {
+    state = state.copyWith(
+        loadingState: loadState,
+        errorMessage: errorMsg
+    );
+  }
+
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----for_sale_vm-----initPageData   ${state.loadingState}");
+    onRefresh();
+  }
+
+  // 上拉加载 更多
+  Future loadMore() async {
+    _page++;
+    getServicesData();
+  }
+
+
+  // 下拉刷新
+  Future onRefresh() async {
+    _page = 1;
+    getServicesData();
+  }
+
+
+  // 手动进行刷新
+  Future triggerRefresh() async {
+    Log.d("trggerRefresh");
+    refreshController.callRefresh();
+  }
+
+  // 手动进行刷新
+  Future directRefresh() async {
+    state = state.copyWith(datas:null);
+    // 注意:由于 nestedscrollview 嵌套easyfresh 组件  refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口
+    // https://github.com/xuelongqy/flutter_easy_refresh/issues/692
+    refreshController.callRefresh();
+    refreshController.resetFooter();
+    _page = 1;
+    _needShowPlaceholder = true;
+    getServicesData();
+  }
+
+
+  // 重试请求
+  Future retryRequest() async {
+    _page = 1;
+    _needShowPlaceholder = true;
+    getServicesData();
+  }
+
+
+  Future getServicesData<T>() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    try {
+      Map<String, dynamic> params = {
+        "parent_id": null,
+      };
+      final result = await serviceRespositoryInstance.fetchServiceCateGoryList(params);
+      if(result.isSuccess){
+        state = state.copyWith(datas: result.list as List<ServiceCategoryEntity>);
+        changeLoadingState(LoadState.State_Success, null);
+        refreshController.finishRefresh();
+      } 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;
+  }
+  
+  // 去付费服务/维修服务  列表页
+  goToPaidOrRepairListPage(BuildContext context, int id, String type, ServiceCategoryEntity entity){
+    state = state.copyWith(
+        curCategory: entity
+    );
+    if(id == 1){
+      ServicesPage.startInstance(parentCategoryId: 1);
+    }else if(id == 4){
+      RepairPage.startInstance(parentCategoryId: 4);
+    }else {
+      ToastEngine.show("暂未开放");
+    }
+  }
+}

+ 26 - 0
packages/cpt_services/lib/modules/services/services_main_vm.g.dart

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

+ 7 - 4
packages/cpt_services/lib/modules/services/services_page.dart

@@ -27,14 +27,15 @@ final GlobalKey<ExtendedNestedScrollViewState> extendedNestedScrollViewKey =
 GlobalKey<ExtendedNestedScrollViewState>();
 @RoutePage()
 class ServicesPage extends HookConsumerWidget with WidgetsBindingObserver {
-  ServicesPage({Key? key}) : super(key: key);
+  int parentCategoryId = 0; //父级分类id
+  ServicesPage({Key? key, required this.parentCategoryId}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance({BuildContext? context, required int parentCategoryId}) {
     if (context != null) {
-      context.router.push( ServicesPageRoute());
+      context.router.push( ServicesPageRoute(parentCategoryId:parentCategoryId));
     } else {
-      appRouter.push( ServicesPageRoute());
+      appRouter.push( ServicesPageRoute(parentCategoryId:parentCategoryId));
     }
   }
 
@@ -91,6 +92,8 @@ class ServicesPage extends HookConsumerWidget with WidgetsBindingObserver {
     final currentPageIdx = tabsRouterKey.currentState?.controller?.activeIndex ?? 0;
 
     useEffect(() {
+      vm.setInitPageData(context, parentCategoryId);
+
       // 监听窗口
       WidgetsBinding.instance.addObserver(this);
     }, []);

+ 5 - 1
packages/cpt_services/lib/modules/services/services_state.dart

@@ -3,12 +3,14 @@ import 'package:cs_resources/generated/assets.dart';
 
 class ServicesVmState {
   List<Map<String, dynamic>>? topSectionsData;
+
+  int? parentCategoryId;
   int currentPageViewIdx = 0;
   dynamic? tabsRouter;
 
-
   ServicesVmState({
     List<Map<String, dynamic>>? topSectionsData,
+    this.parentCategoryId,
     required this.currentPageViewIdx,
     this.tabsRouter,
   }) : topSectionsData = topSectionsData?? [
@@ -31,11 +33,13 @@ class ServicesVmState {
 
   ServicesVmState copyWith({
     List<Map<String, dynamic>>? topSectionsData,
+    int? parentCategoryId,
     int? currentPageViewIdx,
     dynamic? tabsRouter,
   }) {
     return ServicesVmState(
       topSectionsData: topSectionsData ?? this.topSectionsData,
+      parentCategoryId: parentCategoryId ?? this.parentCategoryId,
       currentPageViewIdx: currentPageViewIdx ?? this.currentPageViewIdx,
       tabsRouter: tabsRouter ?? this.tabsRouter,
     );

+ 18 - 1
packages/cpt_services/lib/modules/services/services_vm.dart

@@ -1,4 +1,7 @@
 
+import 'package:cpt_services/modules/services/history/history_vm.dart';
+import 'package:cpt_services/modules/services/homeService/home_service_vm.dart';
+import 'package:cpt_services/modules/services/inProgress/in_progress_vm.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/cupertino.dart';
@@ -23,6 +26,9 @@ part 'services_vm.g.dart';
 
 @riverpod
 class ServicesVm extends _$ServicesVm {
+
+  late int _parentCategoryId;
+
   get topSectionsData => state.topSectionsData;
   late ServicesRespository servicesRespositoryInstance;
   late Map<int, dynamic> providerMap = {};
@@ -78,6 +84,15 @@ class ServicesVm extends _$ServicesVm {
     return state;
   }
 
+  setInitPageData(BuildContext context, int parentCategoryId){
+    _parentCategoryId = parentCategoryId;
+    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
+      state = state.copyWith(
+        parentCategoryId: parentCategoryId,
+      );
+    });
+  }
+
   // 搜集pageView 对应的vm
   void getPageViewVm(){
     // 每次切换后需要重新获取 一组 pageView的 vm
@@ -86,9 +101,11 @@ class ServicesVm extends _$ServicesVm {
       ServicesPageviewIdxData.values.forEach((key, value) {
         switch(key){
           case 0:
+            providerMap[key] = ref.read(homeServiceVmProvider.notifier);
           case 1:
+            providerMap[key] = ref.read(inProgressVmProvider.notifier);
           case 2:
-          // providerMap[key] = ref.read(forrentVmProvider.notifier);
+          providerMap[key] = ref.read(historyVmProvider.notifier);
         }
       });
     });

+ 1 - 1
packages/cpt_services/lib/modules/services/services_vm.g.dart

@@ -6,7 +6,7 @@ part of 'services_vm.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$servicesVmHash() => r'7805f3c3765a93ec9b488e6e288a5baa346ba2ed';
+String _$servicesVmHash() => r'960eacf01f767979f64ce3c1e026549f5cfda0f4';
 
 /// See also [ServicesVm].
 @ProviderFor(ServicesVm)

+ 51 - 12
packages/cpt_services/lib/respository/services_respository.dart

@@ -5,7 +5,12 @@ import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/myposts_sale_rent_entity.dart';
 import 'package:domain/entity/newsfeed_foryou_entity.dart';
 import 'package:domain/entity/newsfeed_news_entity.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
+import 'package:domain/entity/paid_service_entity.dart';
+import 'package:domain/entity/paid_service_pay_success_info_entity.dart';
 import 'package:domain/entity/server_time.dart';
+import 'package:domain/entity/service_category_entity.dart';
+import 'package:domain/entity/service_time_period_entity.dart';
 import 'package:domain/entity/service_order_detail_entity.dart';
 import 'package:domain/entity/service_evaluate_list_entity.dart';
 import 'package:domain/entity/service_repair_detail_entity.dart';
@@ -63,11 +68,11 @@ class ServicesRespository {
     //根据返回的结果,封装原始数据为Bean/Entity对象
     if (result.isSuccess) {
       //重新赋值data或list
-      final json = result.getDataJson();
-      // var data = NewsfeedForyouEntity.fromJson(json!);
+      final listJson = result.getListJson();
+      var listData = listJson!.map((e) => ServiceCategoryEntity.fromJson(e!)).toList();
       //重新赋值data或list
-      return result.convert(data: json);
-    } else {
+      return result.convert(list: listData);
+    }else  {
       if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
@@ -87,7 +92,6 @@ class ServicesRespository {
     headers["Accept"] = "application/x.yyjobs-api.v1+json";
 
     final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
       '/api/v1/user/service/paid-service/index', // api 地址
       params: params,
       headers: headers,
@@ -103,7 +107,7 @@ class ServicesRespository {
     if (result.isSuccess) {
       //重新赋值data或list
       final json = result.getDataJson();
-      var data = GarageSaleRentEntity.fromJson(json!);
+      var data = PaidServiceEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
     } else {
@@ -253,7 +257,6 @@ class ServicesRespository {
     // headers["Accept"] = "application/x.yyjobs-api.v1+json";
 
     final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
       '/api/v1/user/service/paid-service/detail', // api 地址
       params: params,
       headers: headers,
@@ -269,11 +272,47 @@ class ServicesRespository {
     if (result.isSuccess) {
       //重新赋值data或list
       final json = result.getDataJson();
-      // var data = GarageSaleRentDetailEntity.fromJson(json!);
+      var data = PaidServiceDetailEntity.fromJson(json!);
       //重新赋值data或list
-      return result.convert(data: json);
-    } else {
-      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
+      return result.convert(data: data);
+    }else {
+      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+        ToastEngine.show("${result.errorMsg}");
+      }
+    }
+    return result.convert();
+  }
+
+  // 获取 付费服务 时间段
+  Future<HttpResult<Object>> fetchPaidServiceTimePeriod(
+      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(
+      '/api/v1/user/service/paid-service/time-period', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
+      networkDebounce: false,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final list = result.getListJson();
+      List<ServiceTimePeriodEntity> listEntity= list!.map((e)=>ServiceTimePeriodEntity.fromJson(e)).toList();
+      //重新赋值data或list
+      return result.convert(list: listEntity);
+    }else {
+      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
         ToastEngine.show("${result.errorMsg}");
       }
     }
@@ -307,7 +346,7 @@ class ServicesRespository {
     if (result.isSuccess) {
       //重新赋值data或list
       final json = result.getDataJson();
-      // var data = NewsfeedForyouEntity.fromJson(json!);
+      var data = PaidServicePaySuccessInfoEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
     } else {

+ 73 - 86
packages/cpt_services/lib/router/page/services_page_router.gr.dart

@@ -26,7 +26,7 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
       final args = routeData.argsAs<CleanOrderDetailPageRouteArgs>(
           orElse: () => CleanOrderDetailPageRouteArgs(
                 id: pathParams.getInt('id'),
-                serviceTypeCode: pathParams.getInt('serviceTypeCode'),
+                cleanServiceType: pathParams.getString('cleanServiceType'),
                 serviesStatusCode: pathParams.getInt('serviesStatusCode'),
               ));
       return AutoRoutePage<dynamic>(
@@ -34,7 +34,7 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
         child: CleanOrderDetailPage(
           key: args.key,
           id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
+          cleanServiceType: args.cleanServiceType,
           serviesStatusCode: args.serviesStatusCode,
         ),
       );
@@ -82,11 +82,13 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
       );
     },
     RepairPageRoute.name: (routeData) {
-      final args = routeData.argsAs<RepairPageRouteArgs>(
-          orElse: () => const RepairPageRouteArgs());
+      final args = routeData.argsAs<RepairPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: RepairPage(key: args.key),
+        child: RepairPage(
+          key: args.key,
+          parentCategoryId: args.parentCategoryId,
+        ),
       );
     },
     ServiceCleanDetailPageRoute.name: (routeData) {
@@ -94,14 +96,14 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
       final args = routeData.argsAs<ServiceCleanDetailPageRouteArgs>(
           orElse: () => ServiceCleanDetailPageRouteArgs(
                 id: pathParams.getInt('id'),
-                serviceTypeCode: pathParams.getInt('serviceTypeCode'),
+                cleanServiceType: pathParams.getString('cleanServiceType'),
               ));
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: ServiceCleanDetailPage(
           key: args.key,
           id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
+          cleanServiceType: args.cleanServiceType,
         ),
       );
     },
@@ -112,7 +114,7 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
         child: ServiceEvaluateCreatePage(
           key: args.key,
           id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
+          cleanServiceType: args.cleanServiceType,
         ),
       );
     },
@@ -123,7 +125,7 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
         child: ServiceEvaluateListPage(
           key: args.key,
           id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
+          cleanServiceType: args.cleanServiceType,
         ),
       );
     },
@@ -134,19 +136,14 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
         child: ServiceOrderConfirmPage(
           key: args.key,
           id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
+          cleanServiceType: args.cleanServiceType,
         ),
       );
     },
     ServicePaySuccessPageRoute.name: (routeData) {
-      final args = routeData.argsAs<ServicePaySuccessPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: ServicePaySuccessPage(
-          key: args.key,
-          id: args.id,
-          serviceTypeCode: args.serviceTypeCode,
-        ),
+        child: const ServicePaySuccessPage(),
       );
     },
     ServiceRepairDetailPageRoute.name: (routeData) {
@@ -174,11 +171,13 @@ abstract class _$ServicesPageRouter extends RootStackRouter {
       );
     },
     ServicesPageRoute.name: (routeData) {
-      final args = routeData.argsAs<ServicesPageRouteArgs>(
-          orElse: () => const ServicesPageRouteArgs());
+      final args = routeData.argsAs<ServicesPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: ServicesPage(key: args.key),
+        child: ServicesPage(
+          key: args.key,
+          parentCategoryId: args.parentCategoryId,
+        ),
       );
     },
   };
@@ -205,7 +204,7 @@ class CleanOrderDetailPageRoute
   CleanOrderDetailPageRoute({
     Key? key,
     required int id,
-    required int serviceTypeCode,
+    required String cleanServiceType,
     required int serviesStatusCode,
     List<PageRouteInfo>? children,
   }) : super(
@@ -213,12 +212,12 @@ class CleanOrderDetailPageRoute
           args: CleanOrderDetailPageRouteArgs(
             key: key,
             id: id,
-            serviceTypeCode: serviceTypeCode,
+            cleanServiceType: cleanServiceType,
             serviesStatusCode: serviesStatusCode,
           ),
           rawPathParams: {
             'id': id,
-            'serviceTypeCode': serviceTypeCode,
+            'cleanServiceType': cleanServiceType,
             'serviesStatusCode': serviesStatusCode,
           },
           initialChildren: children,
@@ -234,7 +233,7 @@ class CleanOrderDetailPageRouteArgs {
   const CleanOrderDetailPageRouteArgs({
     this.key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
     required this.serviesStatusCode,
   });
 
@@ -242,13 +241,13 @@ class CleanOrderDetailPageRouteArgs {
 
   final int id;
 
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   final int serviesStatusCode;
 
   @override
   String toString() {
-    return 'CleanOrderDetailPageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode, serviesStatusCode: $serviesStatusCode}';
+    return 'CleanOrderDetailPageRouteArgs{key: $key, id: $id, cleanServiceType: $cleanServiceType, serviesStatusCode: $serviesStatusCode}';
   }
 }
 
@@ -355,10 +354,14 @@ class RepairInProgressPageRoute extends PageRouteInfo<void> {
 class RepairPageRoute extends PageRouteInfo<RepairPageRouteArgs> {
   RepairPageRoute({
     Key? key,
+    required int parentCategoryId,
     List<PageRouteInfo>? children,
   }) : super(
           RepairPageRoute.name,
-          args: RepairPageRouteArgs(key: key),
+          args: RepairPageRouteArgs(
+            key: key,
+            parentCategoryId: parentCategoryId,
+          ),
           initialChildren: children,
         );
 
@@ -369,13 +372,18 @@ class RepairPageRoute extends PageRouteInfo<RepairPageRouteArgs> {
 }
 
 class RepairPageRouteArgs {
-  const RepairPageRouteArgs({this.key});
+  const RepairPageRouteArgs({
+    this.key,
+    required this.parentCategoryId,
+  });
 
   final Key? key;
 
+  final int parentCategoryId;
+
   @override
   String toString() {
-    return 'RepairPageRouteArgs{key: $key}';
+    return 'RepairPageRouteArgs{key: $key, parentCategoryId: $parentCategoryId}';
   }
 }
 
@@ -386,18 +394,18 @@ class ServiceCleanDetailPageRoute
   ServiceCleanDetailPageRoute({
     Key? key,
     required int id,
-    required int serviceTypeCode,
+    required String cleanServiceType,
     List<PageRouteInfo>? children,
   }) : super(
           ServiceCleanDetailPageRoute.name,
           args: ServiceCleanDetailPageRouteArgs(
             key: key,
             id: id,
-            serviceTypeCode: serviceTypeCode,
+            cleanServiceType: cleanServiceType,
           ),
           rawPathParams: {
             'id': id,
-            'serviceTypeCode': serviceTypeCode,
+            'cleanServiceType': cleanServiceType,
           },
           initialChildren: children,
         );
@@ -412,18 +420,18 @@ class ServiceCleanDetailPageRouteArgs {
   const ServiceCleanDetailPageRouteArgs({
     this.key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   });
 
   final Key? key;
 
   final int id;
 
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   @override
   String toString() {
-    return 'ServiceCleanDetailPageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode}';
+    return 'ServiceCleanDetailPageRouteArgs{key: $key, id: $id, cleanServiceType: $cleanServiceType}';
   }
 }
 
@@ -434,14 +442,14 @@ class ServiceEvaluateCreatePageRoute
   ServiceEvaluateCreatePageRoute({
     Key? key,
     required int id,
-    required int serviceTypeCode,
+    required String cleanServiceType,
     List<PageRouteInfo>? children,
   }) : super(
           ServiceEvaluateCreatePageRoute.name,
           args: ServiceEvaluateCreatePageRouteArgs(
             key: key,
             id: id,
-            serviceTypeCode: serviceTypeCode,
+            cleanServiceType: cleanServiceType,
           ),
           initialChildren: children,
         );
@@ -456,18 +464,18 @@ class ServiceEvaluateCreatePageRouteArgs {
   const ServiceEvaluateCreatePageRouteArgs({
     this.key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   });
 
   final Key? key;
 
   final int id;
 
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   @override
   String toString() {
-    return 'ServiceEvaluateCreatePageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode}';
+    return 'ServiceEvaluateCreatePageRouteArgs{key: $key, id: $id, cleanServiceType: $cleanServiceType}';
   }
 }
 
@@ -478,14 +486,14 @@ class ServiceEvaluateListPageRoute
   ServiceEvaluateListPageRoute({
     Key? key,
     required int id,
-    required int serviceTypeCode,
+    required String cleanServiceType,
     List<PageRouteInfo>? children,
   }) : super(
           ServiceEvaluateListPageRoute.name,
           args: ServiceEvaluateListPageRouteArgs(
             key: key,
             id: id,
-            serviceTypeCode: serviceTypeCode,
+            cleanServiceType: cleanServiceType,
           ),
           initialChildren: children,
         );
@@ -500,18 +508,18 @@ class ServiceEvaluateListPageRouteArgs {
   const ServiceEvaluateListPageRouteArgs({
     this.key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   });
 
   final Key? key;
 
   final int id;
 
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   @override
   String toString() {
-    return 'ServiceEvaluateListPageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode}';
+    return 'ServiceEvaluateListPageRouteArgs{key: $key, id: $id, cleanServiceType: $cleanServiceType}';
   }
 }
 
@@ -522,14 +530,14 @@ class ServiceOrderConfirmPageRoute
   ServiceOrderConfirmPageRoute({
     Key? key,
     required int id,
-    required int serviceTypeCode,
+    required String cleanServiceType,
     List<PageRouteInfo>? children,
   }) : super(
           ServiceOrderConfirmPageRoute.name,
           args: ServiceOrderConfirmPageRouteArgs(
             key: key,
             id: id,
-            serviceTypeCode: serviceTypeCode,
+            cleanServiceType: cleanServiceType,
           ),
           initialChildren: children,
         );
@@ -544,63 +552,33 @@ class ServiceOrderConfirmPageRouteArgs {
   const ServiceOrderConfirmPageRouteArgs({
     this.key,
     required this.id,
-    required this.serviceTypeCode,
+    required this.cleanServiceType,
   });
 
   final Key? key;
 
   final int id;
 
-  final int serviceTypeCode;
+  final String cleanServiceType;
 
   @override
   String toString() {
-    return 'ServiceOrderConfirmPageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode}';
+    return 'ServiceOrderConfirmPageRouteArgs{key: $key, id: $id, cleanServiceType: $cleanServiceType}';
   }
 }
 
 /// generated route for
 /// [ServicePaySuccessPage]
-class ServicePaySuccessPageRoute
-    extends PageRouteInfo<ServicePaySuccessPageRouteArgs> {
-  ServicePaySuccessPageRoute({
-    Key? key,
-    required int id,
-    required int serviceTypeCode,
-    List<PageRouteInfo>? children,
-  }) : super(
+class ServicePaySuccessPageRoute extends PageRouteInfo<void> {
+  const ServicePaySuccessPageRoute({List<PageRouteInfo>? children})
+      : super(
           ServicePaySuccessPageRoute.name,
-          args: ServicePaySuccessPageRouteArgs(
-            key: key,
-            id: id,
-            serviceTypeCode: serviceTypeCode,
-          ),
           initialChildren: children,
         );
 
   static const String name = 'ServicePaySuccessPageRoute';
 
-  static const PageInfo<ServicePaySuccessPageRouteArgs> page =
-      PageInfo<ServicePaySuccessPageRouteArgs>(name);
-}
-
-class ServicePaySuccessPageRouteArgs {
-  const ServicePaySuccessPageRouteArgs({
-    this.key,
-    required this.id,
-    required this.serviceTypeCode,
-  });
-
-  final Key? key;
-
-  final int id;
-
-  final int serviceTypeCode;
-
-  @override
-  String toString() {
-    return 'ServicePaySuccessPageRouteArgs{key: $key, id: $id, serviceTypeCode: $serviceTypeCode}';
-  }
+  static const PageInfo<void> page = PageInfo<void>(name);
 }
 
 /// generated route for
@@ -685,10 +663,14 @@ class ServicesMainPageRouteArgs {
 class ServicesPageRoute extends PageRouteInfo<ServicesPageRouteArgs> {
   ServicesPageRoute({
     Key? key,
+    required int parentCategoryId,
     List<PageRouteInfo>? children,
   }) : super(
           ServicesPageRoute.name,
-          args: ServicesPageRouteArgs(key: key),
+          args: ServicesPageRouteArgs(
+            key: key,
+            parentCategoryId: parentCategoryId,
+          ),
           initialChildren: children,
         );
 
@@ -699,12 +681,17 @@ class ServicesPageRoute extends PageRouteInfo<ServicesPageRouteArgs> {
 }
 
 class ServicesPageRouteArgs {
-  const ServicesPageRouteArgs({this.key});
+  const ServicesPageRouteArgs({
+    this.key,
+    required this.parentCategoryId,
+  });
 
   final Key? key;
 
+  final int parentCategoryId;
+
   @override
   String toString() {
-    return 'ServicesPageRouteArgs{key: $key}';
+    return 'ServicesPageRouteArgs{key: $key, parentCategoryId: $parentCategoryId}';
   }
 }

+ 137 - 0
packages/cs_domain/lib/entity/paid_service_detail_entity.dart

@@ -0,0 +1,137 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/paid_service_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/paid_service_detail_entity.g.dart';
+
+@JsonSerializable()
+class PaidServiceDetailEntity {
+	int? id;
+	List<String>? resources;
+	String? name;
+	@JSONField(name: "evaluations_avg_score")
+	int? evaluationsAvgScore;
+	String? highlight;
+	@JSONField(name: "urgent_price")
+	int? urgentPrice;
+	@JSONField(name: "holiday_price")
+	int? holidayPrice;
+	@JSONField(name: "night_price")
+	double? nightPrice;
+	@JSONField(name: "service_period_start")
+	String? servicePeriodStart;
+	@JSONField(name: "service_period_end")
+	String? servicePeriodEnd;
+	@JSONField(name: "service_period_interval")
+	int? servicePeriodInterval;
+	String? description;
+	PaidServiceDetailMerchant? merchant;
+	PaidServiceDetailCategory? category;
+	List<PaidServiceDetailProducts>? products;
+	List<PaidServiceDetailEvaluations>? evaluations;
+
+	PaidServiceDetailEntity();
+
+	factory PaidServiceDetailEntity.fromJson(Map<String, dynamic> json) => $PaidServiceDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceDetailMerchant {
+	int? id;
+	String? name;
+
+	PaidServiceDetailMerchant();
+
+	factory PaidServiceDetailMerchant.fromJson(Map<String, dynamic> json) => $PaidServiceDetailMerchantFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailMerchantToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceDetailCategory {
+	int? id;
+	String? name;
+	String? type;
+
+	PaidServiceDetailCategory();
+
+	factory PaidServiceDetailCategory.fromJson(Map<String, dynamic> json) => $PaidServiceDetailCategoryFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailCategoryToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceDetailProducts {
+	int? id;
+	String? name;
+	@JSONField(name: "short_description")
+	String? shortDescription;
+	int? price;
+
+	PaidServiceDetailProducts();
+
+	factory PaidServiceDetailProducts.fromJson(Map<String, dynamic> json) => $PaidServiceDetailProductsFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailProductsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceDetailEvaluations {
+	int? id;
+	int? score;
+	String? comment;
+	List<String>? resources;
+	PaidServiceDetailEvaluationsAccount? account;
+	@JSONField(name: "created_at")
+	String? createdAt;
+
+	PaidServiceDetailEvaluations();
+
+	factory PaidServiceDetailEvaluations.fromJson(Map<String, dynamic> json) => $PaidServiceDetailEvaluationsFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailEvaluationsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceDetailEvaluationsAccount {
+	int? id;
+	String? name;
+	String? avatar;
+
+	PaidServiceDetailEvaluationsAccount();
+
+	factory PaidServiceDetailEvaluationsAccount.fromJson(Map<String, dynamic> json) => $PaidServiceDetailEvaluationsAccountFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceDetailEvaluationsAccountToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 85 - 0
packages/cs_domain/lib/entity/paid_service_entity.dart

@@ -0,0 +1,85 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/paid_service_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/paid_service_entity.g.dart';
+
+@JsonSerializable()
+class PaidServiceEntity {
+	int? count;
+	int? page;
+	int? limit;
+	@JSONField(name: "count_page")
+	int? countPage;
+	List<PaidServiceList>? list;
+
+	PaidServiceEntity();
+
+	factory PaidServiceEntity.fromJson(Map<String, dynamic> json) => $PaidServiceEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceList {
+	int? id;
+	String? name;
+	List<String>? resources;
+	@JSONField(name: "lowest_price")
+	int? lowestPrice;
+	@JSONField(name: "likes_count")
+	int? likesCount;
+	bool? liked;
+	PaidServiceListMerchant? merchant;
+	PaidServiceListCategory? category;
+
+	PaidServiceList();
+
+	factory PaidServiceList.fromJson(Map<String, dynamic> json) => $PaidServiceListFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceListMerchant {
+	int? id;
+	String? name;
+
+	PaidServiceListMerchant();
+
+	factory PaidServiceListMerchant.fromJson(Map<String, dynamic> json) => $PaidServiceListMerchantFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceListMerchantToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServiceListCategory {
+	int? id;
+	String? name;
+	String? type;
+
+	PaidServiceListCategory();
+
+	factory PaidServiceListCategory.fromJson(Map<String, dynamic> json) => $PaidServiceListCategoryFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServiceListCategoryToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 169 - 0
packages/cs_domain/lib/entity/paid_service_pay_success_info_entity.dart

@@ -0,0 +1,169 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/paid_service_pay_success_info_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/paid_service_pay_success_info_entity.g.dart';
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoEntity {
+	String? id;
+	String? sn;
+	@JSONField(name: "total_amount")
+	int? totalAmount;
+	@JSONField(name: "paid_at")
+	String? paidAt;
+	String? notes;
+	PaidServicePaySuccessInfoAccount? account;
+	@JSONField(name: "order_service")
+	PaidServicePaySuccessInfoOrderService? orderService;
+	PaidServicePaySuccessInfoMerchant? merchant;
+	PaidServicePaySuccessInfoStaff? staff;
+	@JSONField(name: "order_products")
+	PaidServicePaySuccessInfoOrderProducts? orderProducts;
+	PaidServicePaySuccessInfoEstate? estate;
+	@JSONField(name: "estate_unit")
+	PaidServicePaySuccessInfoEstateUnit? estateUnit;
+
+	PaidServicePaySuccessInfoEntity();
+
+	factory PaidServicePaySuccessInfoEntity.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoAccount {
+	String? id;
+	String? name;
+	String? avatar;
+	String? phone;
+
+	PaidServicePaySuccessInfoAccount();
+
+	factory PaidServicePaySuccessInfoAccount.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoAccountFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoAccountToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoOrderService {
+	String? id;
+	String? name;
+	@JSONField(name: "evaluations_avg_score")
+	int? evaluationsAvgScore;
+
+	PaidServicePaySuccessInfoOrderService();
+
+	factory PaidServicePaySuccessInfoOrderService.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoOrderServiceFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoOrderServiceToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoMerchant {
+	String? id;
+	String? name;
+	@JSONField(name: "contact_phone")
+	String? contactPhone;
+
+	PaidServicePaySuccessInfoMerchant();
+
+	factory PaidServicePaySuccessInfoMerchant.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoMerchantFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoMerchantToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoStaff {
+	String? id;
+	String? name;
+	String? phone;
+
+	PaidServicePaySuccessInfoStaff();
+
+	factory PaidServicePaySuccessInfoStaff.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoStaffFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoStaffToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoOrderProducts {
+	String? id;
+	@JSONField(name: "product_name")
+	String? productName;
+	int? quantity;
+	@JSONField(name: "total_amount")
+	int? totalAmount;
+	@JSONField(name: "planned_service_at")
+	String? plannedServiceAt;
+
+	PaidServicePaySuccessInfoOrderProducts();
+
+	factory PaidServicePaySuccessInfoOrderProducts.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoOrderProductsFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoOrderProductsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoEstate {
+	String? id;
+	String? name;
+
+	PaidServicePaySuccessInfoEstate();
+
+	factory PaidServicePaySuccessInfoEstate.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoEstateFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoEstateToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class PaidServicePaySuccessInfoEstateUnit {
+	String? id;
+	String? unit;
+	String? address;
+
+	PaidServicePaySuccessInfoEstateUnit();
+
+	factory PaidServicePaySuccessInfoEstateUnit.fromJson(Map<String, dynamic> json) => $PaidServicePaySuccessInfoEstateUnitFromJson(json);
+
+	Map<String, dynamic> toJson() => $PaidServicePaySuccessInfoEstateUnitToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 24 - 0
packages/cs_domain/lib/entity/service_category_entity.dart

@@ -0,0 +1,24 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/service_category_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/service_category_entity.g.dart';
+
+@JsonSerializable()
+class ServiceCategoryEntity {
+	int? id;
+	String? name;
+	@JSONField(name: "parent_id")
+	int? parentId;
+	String? type;
+
+	ServiceCategoryEntity();
+
+	factory ServiceCategoryEntity.fromJson(Map<String, dynamic> json) => $ServiceCategoryEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceCategoryEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 26 - 0
packages/cs_domain/lib/entity/service_time_period_entity.dart

@@ -0,0 +1,26 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/service_time_period_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/service_time_period_entity.g.dart';
+
+@JsonSerializable()
+class ServiceTimePeriodEntity {
+	@JSONField(name: "time_text")
+	String? timeText;
+	String? time;
+	bool? urgent;
+	bool? holiday;
+	bool? night;
+	bool? enable;
+
+	ServiceTimePeriodEntity();
+
+	factory ServiceTimePeriodEntity.fromJson(Map<String, dynamic> json) => $ServiceTimePeriodEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceTimePeriodEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

File diff suppressed because it is too large
+ 458 - 172
packages/cs_domain/lib/generated/json/base/json_convert_content.dart


+ 374 - 0
packages/cs_domain/lib/generated/json/paid_service_detail_entity.g.dart

@@ -0,0 +1,374 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/paid_service_detail_entity.dart';
+
+PaidServiceDetailEntity $PaidServiceDetailEntityFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailEntity paidServiceDetailEntity = PaidServiceDetailEntity();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailEntity.id = id;
+  }
+  final List<String>? resources = (json['resources'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (resources != null) {
+    paidServiceDetailEntity.resources = resources;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceDetailEntity.name = name;
+  }
+  final int? evaluationsAvgScore = jsonConvert.convert<int>(
+      json['evaluations_avg_score']);
+  if (evaluationsAvgScore != null) {
+    paidServiceDetailEntity.evaluationsAvgScore = evaluationsAvgScore;
+  }
+  final String? highlight = jsonConvert.convert<String>(json['highlight']);
+  if (highlight != null) {
+    paidServiceDetailEntity.highlight = highlight;
+  }
+  final int? urgentPrice = jsonConvert.convert<int>(json['urgent_price']);
+  if (urgentPrice != null) {
+    paidServiceDetailEntity.urgentPrice = urgentPrice;
+  }
+  final int? holidayPrice = jsonConvert.convert<int>(json['holiday_price']);
+  if (holidayPrice != null) {
+    paidServiceDetailEntity.holidayPrice = holidayPrice;
+  }
+  final double? nightPrice = jsonConvert.convert<double>(json['night_price']);
+  if (nightPrice != null) {
+    paidServiceDetailEntity.nightPrice = nightPrice;
+  }
+  final String? servicePeriodStart = jsonConvert.convert<String>(
+      json['service_period_start']);
+  if (servicePeriodStart != null) {
+    paidServiceDetailEntity.servicePeriodStart = servicePeriodStart;
+  }
+  final String? servicePeriodEnd = jsonConvert.convert<String>(
+      json['service_period_end']);
+  if (servicePeriodEnd != null) {
+    paidServiceDetailEntity.servicePeriodEnd = servicePeriodEnd;
+  }
+  final int? servicePeriodInterval = jsonConvert.convert<int>(
+      json['service_period_interval']);
+  if (servicePeriodInterval != null) {
+    paidServiceDetailEntity.servicePeriodInterval = servicePeriodInterval;
+  }
+  final String? description = jsonConvert.convert<String>(json['description']);
+  if (description != null) {
+    paidServiceDetailEntity.description = description;
+  }
+  final PaidServiceDetailMerchant? merchant = jsonConvert.convert<
+      PaidServiceDetailMerchant>(json['merchant']);
+  if (merchant != null) {
+    paidServiceDetailEntity.merchant = merchant;
+  }
+  final PaidServiceDetailCategory? category = jsonConvert.convert<
+      PaidServiceDetailCategory>(json['category']);
+  if (category != null) {
+    paidServiceDetailEntity.category = category;
+  }
+  final List<PaidServiceDetailProducts>? products = (json['products'] as List<
+      dynamic>?)?.map(
+          (e) =>
+      jsonConvert.convert<PaidServiceDetailProducts>(
+          e) as PaidServiceDetailProducts).toList();
+  if (products != null) {
+    paidServiceDetailEntity.products = products;
+  }
+  final List<
+      PaidServiceDetailEvaluations>? evaluations = (json['evaluations'] as List<
+      dynamic>?)?.map(
+          (e) =>
+      jsonConvert.convert<PaidServiceDetailEvaluations>(
+          e) as PaidServiceDetailEvaluations).toList();
+  if (evaluations != null) {
+    paidServiceDetailEntity.evaluations = evaluations;
+  }
+  return paidServiceDetailEntity;
+}
+
+Map<String, dynamic> $PaidServiceDetailEntityToJson(
+    PaidServiceDetailEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['resources'] = entity.resources;
+  data['name'] = entity.name;
+  data['evaluations_avg_score'] = entity.evaluationsAvgScore;
+  data['highlight'] = entity.highlight;
+  data['urgent_price'] = entity.urgentPrice;
+  data['holiday_price'] = entity.holidayPrice;
+  data['night_price'] = entity.nightPrice;
+  data['service_period_start'] = entity.servicePeriodStart;
+  data['service_period_end'] = entity.servicePeriodEnd;
+  data['service_period_interval'] = entity.servicePeriodInterval;
+  data['description'] = entity.description;
+  data['merchant'] = entity.merchant?.toJson();
+  data['category'] = entity.category?.toJson();
+  data['products'] = entity.products?.map((v) => v.toJson()).toList();
+  data['evaluations'] = entity.evaluations?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension PaidServiceDetailEntityExtension on PaidServiceDetailEntity {
+  PaidServiceDetailEntity copyWith({
+    int? id,
+    List<String>? resources,
+    String? name,
+    int? evaluationsAvgScore,
+    String? highlight,
+    int? urgentPrice,
+    int? holidayPrice,
+    double? nightPrice,
+    String? servicePeriodStart,
+    String? servicePeriodEnd,
+    int? servicePeriodInterval,
+    String? description,
+    PaidServiceDetailMerchant? merchant,
+    PaidServiceDetailCategory? category,
+    List<PaidServiceDetailProducts>? products,
+    List<PaidServiceDetailEvaluations>? evaluations,
+  }) {
+    return PaidServiceDetailEntity()
+      ..id = id ?? this.id
+      ..resources = resources ?? this.resources
+      ..name = name ?? this.name
+      ..evaluationsAvgScore = evaluationsAvgScore ?? this.evaluationsAvgScore
+      ..highlight = highlight ?? this.highlight
+      ..urgentPrice = urgentPrice ?? this.urgentPrice
+      ..holidayPrice = holidayPrice ?? this.holidayPrice
+      ..nightPrice = nightPrice ?? this.nightPrice
+      ..servicePeriodStart = servicePeriodStart ?? this.servicePeriodStart
+      ..servicePeriodEnd = servicePeriodEnd ?? this.servicePeriodEnd
+      ..servicePeriodInterval = servicePeriodInterval ??
+          this.servicePeriodInterval
+      ..description = description ?? this.description
+      ..merchant = merchant ?? this.merchant
+      ..category = category ?? this.category
+      ..products = products ?? this.products
+      ..evaluations = evaluations ?? this.evaluations;
+  }
+}
+
+PaidServiceDetailMerchant $PaidServiceDetailMerchantFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailMerchant paidServiceDetailMerchant = PaidServiceDetailMerchant();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailMerchant.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceDetailMerchant.name = name;
+  }
+  return paidServiceDetailMerchant;
+}
+
+Map<String, dynamic> $PaidServiceDetailMerchantToJson(
+    PaidServiceDetailMerchant entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  return data;
+}
+
+extension PaidServiceDetailMerchantExtension on PaidServiceDetailMerchant {
+  PaidServiceDetailMerchant copyWith({
+    int? id,
+    String? name,
+  }) {
+    return PaidServiceDetailMerchant()
+      ..id = id ?? this.id
+      ..name = name ?? this.name;
+  }
+}
+
+PaidServiceDetailCategory $PaidServiceDetailCategoryFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailCategory paidServiceDetailCategory = PaidServiceDetailCategory();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailCategory.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceDetailCategory.name = name;
+  }
+  final String? type = jsonConvert.convert<String>(json['type']);
+  if (type != null) {
+    paidServiceDetailCategory.type = type;
+  }
+  return paidServiceDetailCategory;
+}
+
+Map<String, dynamic> $PaidServiceDetailCategoryToJson(
+    PaidServiceDetailCategory entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['type'] = entity.type;
+  return data;
+}
+
+extension PaidServiceDetailCategoryExtension on PaidServiceDetailCategory {
+  PaidServiceDetailCategory copyWith({
+    int? id,
+    String? name,
+    String? type,
+  }) {
+    return PaidServiceDetailCategory()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..type = type ?? this.type;
+  }
+}
+
+PaidServiceDetailProducts $PaidServiceDetailProductsFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailProducts paidServiceDetailProducts = PaidServiceDetailProducts();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailProducts.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceDetailProducts.name = name;
+  }
+  final String? shortDescription = jsonConvert.convert<String>(
+      json['short_description']);
+  if (shortDescription != null) {
+    paidServiceDetailProducts.shortDescription = shortDescription;
+  }
+  final int? price = jsonConvert.convert<int>(json['price']);
+  if (price != null) {
+    paidServiceDetailProducts.price = price;
+  }
+  return paidServiceDetailProducts;
+}
+
+Map<String, dynamic> $PaidServiceDetailProductsToJson(
+    PaidServiceDetailProducts entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['short_description'] = entity.shortDescription;
+  data['price'] = entity.price;
+  return data;
+}
+
+extension PaidServiceDetailProductsExtension on PaidServiceDetailProducts {
+  PaidServiceDetailProducts copyWith({
+    int? id,
+    String? name,
+    String? shortDescription,
+    int? price,
+  }) {
+    return PaidServiceDetailProducts()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..shortDescription = shortDescription ?? this.shortDescription
+      ..price = price ?? this.price;
+  }
+}
+
+PaidServiceDetailEvaluations $PaidServiceDetailEvaluationsFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailEvaluations paidServiceDetailEvaluations = PaidServiceDetailEvaluations();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailEvaluations.id = id;
+  }
+  final int? score = jsonConvert.convert<int>(json['score']);
+  if (score != null) {
+    paidServiceDetailEvaluations.score = score;
+  }
+  final String? comment = jsonConvert.convert<String>(json['comment']);
+  if (comment != null) {
+    paidServiceDetailEvaluations.comment = comment;
+  }
+  final List<String>? resources = (json['resources'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (resources != null) {
+    paidServiceDetailEvaluations.resources = resources;
+  }
+  final PaidServiceDetailEvaluationsAccount? account = jsonConvert.convert<
+      PaidServiceDetailEvaluationsAccount>(json['account']);
+  if (account != null) {
+    paidServiceDetailEvaluations.account = account;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    paidServiceDetailEvaluations.createdAt = createdAt;
+  }
+  return paidServiceDetailEvaluations;
+}
+
+Map<String, dynamic> $PaidServiceDetailEvaluationsToJson(
+    PaidServiceDetailEvaluations entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['score'] = entity.score;
+  data['comment'] = entity.comment;
+  data['resources'] = entity.resources;
+  data['account'] = entity.account?.toJson();
+  data['created_at'] = entity.createdAt;
+  return data;
+}
+
+extension PaidServiceDetailEvaluationsExtension on PaidServiceDetailEvaluations {
+  PaidServiceDetailEvaluations copyWith({
+    int? id,
+    int? score,
+    String? comment,
+    List<String>? resources,
+    PaidServiceDetailEvaluationsAccount? account,
+    String? createdAt,
+  }) {
+    return PaidServiceDetailEvaluations()
+      ..id = id ?? this.id
+      ..score = score ?? this.score
+      ..comment = comment ?? this.comment
+      ..resources = resources ?? this.resources
+      ..account = account ?? this.account
+      ..createdAt = createdAt ?? this.createdAt;
+  }
+}
+
+PaidServiceDetailEvaluationsAccount $PaidServiceDetailEvaluationsAccountFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceDetailEvaluationsAccount paidServiceDetailEvaluationsAccount = PaidServiceDetailEvaluationsAccount();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceDetailEvaluationsAccount.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceDetailEvaluationsAccount.name = name;
+  }
+  final String? avatar = jsonConvert.convert<String>(json['avatar']);
+  if (avatar != null) {
+    paidServiceDetailEvaluationsAccount.avatar = avatar;
+  }
+  return paidServiceDetailEvaluationsAccount;
+}
+
+Map<String, dynamic> $PaidServiceDetailEvaluationsAccountToJson(
+    PaidServiceDetailEvaluationsAccount entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['avatar'] = entity.avatar;
+  return data;
+}
+
+extension PaidServiceDetailEvaluationsAccountExtension on PaidServiceDetailEvaluationsAccount {
+  PaidServiceDetailEvaluationsAccount copyWith({
+    int? id,
+    String? name,
+    String? avatar,
+  }) {
+    return PaidServiceDetailEvaluationsAccount()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..avatar = avatar ?? this.avatar;
+  }
+}

+ 206 - 0
packages/cs_domain/lib/generated/json/paid_service_entity.g.dart

@@ -0,0 +1,206 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/paid_service_entity.dart';
+
+PaidServiceEntity $PaidServiceEntityFromJson(Map<String, dynamic> json) {
+  final PaidServiceEntity paidServiceEntity = PaidServiceEntity();
+  final int? count = jsonConvert.convert<int>(json['count']);
+  if (count != null) {
+    paidServiceEntity.count = count;
+  }
+  final int? page = jsonConvert.convert<int>(json['page']);
+  if (page != null) {
+    paidServiceEntity.page = page;
+  }
+  final int? limit = jsonConvert.convert<int>(json['limit']);
+  if (limit != null) {
+    paidServiceEntity.limit = limit;
+  }
+  final int? countPage = jsonConvert.convert<int>(json['count_page']);
+  if (countPage != null) {
+    paidServiceEntity.countPage = countPage;
+  }
+  final List<PaidServiceList>? list = (json['list'] as List<dynamic>?)
+      ?.map(
+          (e) => jsonConvert.convert<PaidServiceList>(e) as PaidServiceList)
+      .toList();
+  if (list != null) {
+    paidServiceEntity.list = list;
+  }
+  return paidServiceEntity;
+}
+
+Map<String, dynamic> $PaidServiceEntityToJson(PaidServiceEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['count'] = entity.count;
+  data['page'] = entity.page;
+  data['limit'] = entity.limit;
+  data['count_page'] = entity.countPage;
+  data['list'] = entity.list?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension PaidServiceEntityExtension on PaidServiceEntity {
+  PaidServiceEntity copyWith({
+    int? count,
+    int? page,
+    int? limit,
+    int? countPage,
+    List<PaidServiceList>? list,
+  }) {
+    return PaidServiceEntity()
+      ..count = count ?? this.count
+      ..page = page ?? this.page
+      ..limit = limit ?? this.limit
+      ..countPage = countPage ?? this.countPage
+      ..list = list ?? this.list;
+  }
+}
+
+PaidServiceList $PaidServiceListFromJson(Map<String, dynamic> json) {
+  final PaidServiceList paidServiceList = PaidServiceList();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceList.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceList.name = name;
+  }
+  final List<String>? resources = (json['resources'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (resources != null) {
+    paidServiceList.resources = resources;
+  }
+  final int? lowestPrice = jsonConvert.convert<int>(json['lowest_price']);
+  if (lowestPrice != null) {
+    paidServiceList.lowestPrice = lowestPrice;
+  }
+  final int? likesCount = jsonConvert.convert<int>(json['likes_count']);
+  if (likesCount != null) {
+    paidServiceList.likesCount = likesCount;
+  }
+  final bool? liked = jsonConvert.convert<bool>(json['liked']);
+  if (liked != null) {
+    paidServiceList.liked = liked;
+  }
+  final PaidServiceListMerchant? merchant = jsonConvert.convert<
+      PaidServiceListMerchant>(json['merchant']);
+  if (merchant != null) {
+    paidServiceList.merchant = merchant;
+  }
+  final PaidServiceListCategory? category = jsonConvert.convert<
+      PaidServiceListCategory>(json['category']);
+  if (category != null) {
+    paidServiceList.category = category;
+  }
+  return paidServiceList;
+}
+
+Map<String, dynamic> $PaidServiceListToJson(PaidServiceList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['resources'] = entity.resources;
+  data['lowest_price'] = entity.lowestPrice;
+  data['likes_count'] = entity.likesCount;
+  data['liked'] = entity.liked;
+  data['merchant'] = entity.merchant?.toJson();
+  data['category'] = entity.category?.toJson();
+  return data;
+}
+
+extension PaidServiceListExtension on PaidServiceList {
+  PaidServiceList copyWith({
+    int? id,
+    String? name,
+    List<String>? resources,
+    int? lowestPrice,
+    int? likesCount,
+    bool? liked,
+    PaidServiceListMerchant? merchant,
+    PaidServiceListCategory? category,
+  }) {
+    return PaidServiceList()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..resources = resources ?? this.resources
+      ..lowestPrice = lowestPrice ?? this.lowestPrice
+      ..likesCount = likesCount ?? this.likesCount
+      ..liked = liked ?? this.liked
+      ..merchant = merchant ?? this.merchant
+      ..category = category ?? this.category;
+  }
+}
+
+PaidServiceListMerchant $PaidServiceListMerchantFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceListMerchant paidServiceListMerchant = PaidServiceListMerchant();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceListMerchant.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceListMerchant.name = name;
+  }
+  return paidServiceListMerchant;
+}
+
+Map<String, dynamic> $PaidServiceListMerchantToJson(
+    PaidServiceListMerchant entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  return data;
+}
+
+extension PaidServiceListMerchantExtension on PaidServiceListMerchant {
+  PaidServiceListMerchant copyWith({
+    int? id,
+    String? name,
+  }) {
+    return PaidServiceListMerchant()
+      ..id = id ?? this.id
+      ..name = name ?? this.name;
+  }
+}
+
+PaidServiceListCategory $PaidServiceListCategoryFromJson(
+    Map<String, dynamic> json) {
+  final PaidServiceListCategory paidServiceListCategory = PaidServiceListCategory();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    paidServiceListCategory.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServiceListCategory.name = name;
+  }
+  final String? type = jsonConvert.convert<String>(json['type']);
+  if (type != null) {
+    paidServiceListCategory.type = type;
+  }
+  return paidServiceListCategory;
+}
+
+Map<String, dynamic> $PaidServiceListCategoryToJson(
+    PaidServiceListCategory entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['type'] = entity.type;
+  return data;
+}
+
+extension PaidServiceListCategoryExtension on PaidServiceListCategory {
+  PaidServiceListCategory copyWith({
+    int? id,
+    String? name,
+    String? type,
+  }) {
+    return PaidServiceListCategory()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..type = type ?? this.type;
+  }
+}

+ 410 - 0
packages/cs_domain/lib/generated/json/paid_service_pay_success_info_entity.g.dart

@@ -0,0 +1,410 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/paid_service_pay_success_info_entity.dart';
+
+PaidServicePaySuccessInfoEntity $PaidServicePaySuccessInfoEntityFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoEntity paidServicePaySuccessInfoEntity = PaidServicePaySuccessInfoEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoEntity.id = id;
+  }
+  final String? sn = jsonConvert.convert<String>(json['sn']);
+  if (sn != null) {
+    paidServicePaySuccessInfoEntity.sn = sn;
+  }
+  final int? totalAmount = jsonConvert.convert<int>(json['total_amount']);
+  if (totalAmount != null) {
+    paidServicePaySuccessInfoEntity.totalAmount = totalAmount;
+  }
+  final String? paidAt = jsonConvert.convert<String>(json['paid_at']);
+  if (paidAt != null) {
+    paidServicePaySuccessInfoEntity.paidAt = paidAt;
+  }
+  final String? notes = jsonConvert.convert<String>(json['notes']);
+  if (notes != null) {
+    paidServicePaySuccessInfoEntity.notes = notes;
+  }
+  final PaidServicePaySuccessInfoAccount? account = jsonConvert.convert<
+      PaidServicePaySuccessInfoAccount>(json['account']);
+  if (account != null) {
+    paidServicePaySuccessInfoEntity.account = account;
+  }
+  final PaidServicePaySuccessInfoOrderService? orderService = jsonConvert
+      .convert<PaidServicePaySuccessInfoOrderService>(json['order_service']);
+  if (orderService != null) {
+    paidServicePaySuccessInfoEntity.orderService = orderService;
+  }
+  final PaidServicePaySuccessInfoMerchant? merchant = jsonConvert.convert<
+      PaidServicePaySuccessInfoMerchant>(json['merchant']);
+  if (merchant != null) {
+    paidServicePaySuccessInfoEntity.merchant = merchant;
+  }
+  final PaidServicePaySuccessInfoStaff? staff = jsonConvert.convert<
+      PaidServicePaySuccessInfoStaff>(json['staff']);
+  if (staff != null) {
+    paidServicePaySuccessInfoEntity.staff = staff;
+  }
+  final PaidServicePaySuccessInfoOrderProducts? orderProducts = jsonConvert
+      .convert<PaidServicePaySuccessInfoOrderProducts>(json['order_products']);
+  if (orderProducts != null) {
+    paidServicePaySuccessInfoEntity.orderProducts = orderProducts;
+  }
+  final PaidServicePaySuccessInfoEstate? estate = jsonConvert.convert<
+      PaidServicePaySuccessInfoEstate>(json['estate']);
+  if (estate != null) {
+    paidServicePaySuccessInfoEntity.estate = estate;
+  }
+  final PaidServicePaySuccessInfoEstateUnit? estateUnit = jsonConvert.convert<
+      PaidServicePaySuccessInfoEstateUnit>(json['estate_unit']);
+  if (estateUnit != null) {
+    paidServicePaySuccessInfoEntity.estateUnit = estateUnit;
+  }
+  return paidServicePaySuccessInfoEntity;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoEntityToJson(
+    PaidServicePaySuccessInfoEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['sn'] = entity.sn;
+  data['total_amount'] = entity.totalAmount;
+  data['paid_at'] = entity.paidAt;
+  data['notes'] = entity.notes;
+  data['account'] = entity.account?.toJson();
+  data['order_service'] = entity.orderService?.toJson();
+  data['merchant'] = entity.merchant?.toJson();
+  data['staff'] = entity.staff?.toJson();
+  data['order_products'] = entity.orderProducts?.toJson();
+  data['estate'] = entity.estate?.toJson();
+  data['estate_unit'] = entity.estateUnit?.toJson();
+  return data;
+}
+
+extension PaidServicePaySuccessInfoEntityExtension on PaidServicePaySuccessInfoEntity {
+  PaidServicePaySuccessInfoEntity copyWith({
+    String? id,
+    String? sn,
+    int? totalAmount,
+    String? paidAt,
+    String? notes,
+    PaidServicePaySuccessInfoAccount? account,
+    PaidServicePaySuccessInfoOrderService? orderService,
+    PaidServicePaySuccessInfoMerchant? merchant,
+    PaidServicePaySuccessInfoStaff? staff,
+    PaidServicePaySuccessInfoOrderProducts? orderProducts,
+    PaidServicePaySuccessInfoEstate? estate,
+    PaidServicePaySuccessInfoEstateUnit? estateUnit,
+  }) {
+    return PaidServicePaySuccessInfoEntity()
+      ..id = id ?? this.id
+      ..sn = sn ?? this.sn
+      ..totalAmount = totalAmount ?? this.totalAmount
+      ..paidAt = paidAt ?? this.paidAt
+      ..notes = notes ?? this.notes
+      ..account = account ?? this.account
+      ..orderService = orderService ?? this.orderService
+      ..merchant = merchant ?? this.merchant
+      ..staff = staff ?? this.staff
+      ..orderProducts = orderProducts ?? this.orderProducts
+      ..estate = estate ?? this.estate
+      ..estateUnit = estateUnit ?? this.estateUnit;
+  }
+}
+
+PaidServicePaySuccessInfoAccount $PaidServicePaySuccessInfoAccountFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoAccount paidServicePaySuccessInfoAccount = PaidServicePaySuccessInfoAccount();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoAccount.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServicePaySuccessInfoAccount.name = name;
+  }
+  final String? avatar = jsonConvert.convert<String>(json['avatar']);
+  if (avatar != null) {
+    paidServicePaySuccessInfoAccount.avatar = avatar;
+  }
+  final String? phone = jsonConvert.convert<String>(json['phone']);
+  if (phone != null) {
+    paidServicePaySuccessInfoAccount.phone = phone;
+  }
+  return paidServicePaySuccessInfoAccount;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoAccountToJson(
+    PaidServicePaySuccessInfoAccount entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['avatar'] = entity.avatar;
+  data['phone'] = entity.phone;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoAccountExtension on PaidServicePaySuccessInfoAccount {
+  PaidServicePaySuccessInfoAccount copyWith({
+    String? id,
+    String? name,
+    String? avatar,
+    String? phone,
+  }) {
+    return PaidServicePaySuccessInfoAccount()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..avatar = avatar ?? this.avatar
+      ..phone = phone ?? this.phone;
+  }
+}
+
+PaidServicePaySuccessInfoOrderService $PaidServicePaySuccessInfoOrderServiceFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoOrderService paidServicePaySuccessInfoOrderService = PaidServicePaySuccessInfoOrderService();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoOrderService.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServicePaySuccessInfoOrderService.name = name;
+  }
+  final int? evaluationsAvgScore = jsonConvert.convert<int>(
+      json['evaluations_avg_score']);
+  if (evaluationsAvgScore != null) {
+    paidServicePaySuccessInfoOrderService.evaluationsAvgScore =
+        evaluationsAvgScore;
+  }
+  return paidServicePaySuccessInfoOrderService;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoOrderServiceToJson(
+    PaidServicePaySuccessInfoOrderService entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['evaluations_avg_score'] = entity.evaluationsAvgScore;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoOrderServiceExtension on PaidServicePaySuccessInfoOrderService {
+  PaidServicePaySuccessInfoOrderService copyWith({
+    String? id,
+    String? name,
+    int? evaluationsAvgScore,
+  }) {
+    return PaidServicePaySuccessInfoOrderService()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..evaluationsAvgScore = evaluationsAvgScore ?? this.evaluationsAvgScore;
+  }
+}
+
+PaidServicePaySuccessInfoMerchant $PaidServicePaySuccessInfoMerchantFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoMerchant paidServicePaySuccessInfoMerchant = PaidServicePaySuccessInfoMerchant();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoMerchant.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServicePaySuccessInfoMerchant.name = name;
+  }
+  final String? contactPhone = jsonConvert.convert<String>(
+      json['contact_phone']);
+  if (contactPhone != null) {
+    paidServicePaySuccessInfoMerchant.contactPhone = contactPhone;
+  }
+  return paidServicePaySuccessInfoMerchant;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoMerchantToJson(
+    PaidServicePaySuccessInfoMerchant entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['contact_phone'] = entity.contactPhone;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoMerchantExtension on PaidServicePaySuccessInfoMerchant {
+  PaidServicePaySuccessInfoMerchant copyWith({
+    String? id,
+    String? name,
+    String? contactPhone,
+  }) {
+    return PaidServicePaySuccessInfoMerchant()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..contactPhone = contactPhone ?? this.contactPhone;
+  }
+}
+
+PaidServicePaySuccessInfoStaff $PaidServicePaySuccessInfoStaffFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoStaff paidServicePaySuccessInfoStaff = PaidServicePaySuccessInfoStaff();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoStaff.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServicePaySuccessInfoStaff.name = name;
+  }
+  final String? phone = jsonConvert.convert<String>(json['phone']);
+  if (phone != null) {
+    paidServicePaySuccessInfoStaff.phone = phone;
+  }
+  return paidServicePaySuccessInfoStaff;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoStaffToJson(
+    PaidServicePaySuccessInfoStaff entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['phone'] = entity.phone;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoStaffExtension on PaidServicePaySuccessInfoStaff {
+  PaidServicePaySuccessInfoStaff copyWith({
+    String? id,
+    String? name,
+    String? phone,
+  }) {
+    return PaidServicePaySuccessInfoStaff()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..phone = phone ?? this.phone;
+  }
+}
+
+PaidServicePaySuccessInfoOrderProducts $PaidServicePaySuccessInfoOrderProductsFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoOrderProducts paidServicePaySuccessInfoOrderProducts = PaidServicePaySuccessInfoOrderProducts();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoOrderProducts.id = id;
+  }
+  final String? productName = jsonConvert.convert<String>(json['product_name']);
+  if (productName != null) {
+    paidServicePaySuccessInfoOrderProducts.productName = productName;
+  }
+  final int? quantity = jsonConvert.convert<int>(json['quantity']);
+  if (quantity != null) {
+    paidServicePaySuccessInfoOrderProducts.quantity = quantity;
+  }
+  final int? totalAmount = jsonConvert.convert<int>(json['total_amount']);
+  if (totalAmount != null) {
+    paidServicePaySuccessInfoOrderProducts.totalAmount = totalAmount;
+  }
+  final String? plannedServiceAt = jsonConvert.convert<String>(
+      json['planned_service_at']);
+  if (plannedServiceAt != null) {
+    paidServicePaySuccessInfoOrderProducts.plannedServiceAt = plannedServiceAt;
+  }
+  return paidServicePaySuccessInfoOrderProducts;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoOrderProductsToJson(
+    PaidServicePaySuccessInfoOrderProducts entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['product_name'] = entity.productName;
+  data['quantity'] = entity.quantity;
+  data['total_amount'] = entity.totalAmount;
+  data['planned_service_at'] = entity.plannedServiceAt;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoOrderProductsExtension on PaidServicePaySuccessInfoOrderProducts {
+  PaidServicePaySuccessInfoOrderProducts copyWith({
+    String? id,
+    String? productName,
+    int? quantity,
+    int? totalAmount,
+    String? plannedServiceAt,
+  }) {
+    return PaidServicePaySuccessInfoOrderProducts()
+      ..id = id ?? this.id
+      ..productName = productName ?? this.productName
+      ..quantity = quantity ?? this.quantity
+      ..totalAmount = totalAmount ?? this.totalAmount
+      ..plannedServiceAt = plannedServiceAt ?? this.plannedServiceAt;
+  }
+}
+
+PaidServicePaySuccessInfoEstate $PaidServicePaySuccessInfoEstateFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoEstate paidServicePaySuccessInfoEstate = PaidServicePaySuccessInfoEstate();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoEstate.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    paidServicePaySuccessInfoEstate.name = name;
+  }
+  return paidServicePaySuccessInfoEstate;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoEstateToJson(
+    PaidServicePaySuccessInfoEstate entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoEstateExtension on PaidServicePaySuccessInfoEstate {
+  PaidServicePaySuccessInfoEstate copyWith({
+    String? id,
+    String? name,
+  }) {
+    return PaidServicePaySuccessInfoEstate()
+      ..id = id ?? this.id
+      ..name = name ?? this.name;
+  }
+}
+
+PaidServicePaySuccessInfoEstateUnit $PaidServicePaySuccessInfoEstateUnitFromJson(
+    Map<String, dynamic> json) {
+  final PaidServicePaySuccessInfoEstateUnit paidServicePaySuccessInfoEstateUnit = PaidServicePaySuccessInfoEstateUnit();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    paidServicePaySuccessInfoEstateUnit.id = id;
+  }
+  final String? unit = jsonConvert.convert<String>(json['unit']);
+  if (unit != null) {
+    paidServicePaySuccessInfoEstateUnit.unit = unit;
+  }
+  final String? address = jsonConvert.convert<String>(json['address']);
+  if (address != null) {
+    paidServicePaySuccessInfoEstateUnit.address = address;
+  }
+  return paidServicePaySuccessInfoEstateUnit;
+}
+
+Map<String, dynamic> $PaidServicePaySuccessInfoEstateUnitToJson(
+    PaidServicePaySuccessInfoEstateUnit entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['unit'] = entity.unit;
+  data['address'] = entity.address;
+  return data;
+}
+
+extension PaidServicePaySuccessInfoEstateUnitExtension on PaidServicePaySuccessInfoEstateUnit {
+  PaidServicePaySuccessInfoEstateUnit copyWith({
+    String? id,
+    String? unit,
+    String? address,
+  }) {
+    return PaidServicePaySuccessInfoEstateUnit()
+      ..id = id ?? this.id
+      ..unit = unit ?? this.unit
+      ..address = address ?? this.address;
+  }
+}

+ 49 - 0
packages/cs_domain/lib/generated/json/service_category_entity.g.dart

@@ -0,0 +1,49 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/service_category_entity.dart';
+
+ServiceCategoryEntity $ServiceCategoryEntityFromJson(
+    Map<String, dynamic> json) {
+  final ServiceCategoryEntity serviceCategoryEntity = ServiceCategoryEntity();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    serviceCategoryEntity.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    serviceCategoryEntity.name = name;
+  }
+  final int? parentId = jsonConvert.convert<int>(json['parent_id']);
+  if (parentId != null) {
+    serviceCategoryEntity.parentId = parentId;
+  }
+  final String? type = jsonConvert.convert<String>(json['type']);
+  if (type != null) {
+    serviceCategoryEntity.type = type;
+  }
+  return serviceCategoryEntity;
+}
+
+Map<String, dynamic> $ServiceCategoryEntityToJson(
+    ServiceCategoryEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['parent_id'] = entity.parentId;
+  data['type'] = entity.type;
+  return data;
+}
+
+extension ServiceCategoryEntityExtension on ServiceCategoryEntity {
+  ServiceCategoryEntity copyWith({
+    int? id,
+    String? name,
+    int? parentId,
+    String? type,
+  }) {
+    return ServiceCategoryEntity()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..parentId = parentId ?? this.parentId
+      ..type = type ?? this.type;
+  }
+}

+ 63 - 0
packages/cs_domain/lib/generated/json/service_time_period_entity.g.dart

@@ -0,0 +1,63 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/service_time_period_entity.dart';
+
+ServiceTimePeriodEntity $ServiceTimePeriodEntityFromJson(
+    Map<String, dynamic> json) {
+  final ServiceTimePeriodEntity serviceTimePeriodEntity = ServiceTimePeriodEntity();
+  final String? timeText = jsonConvert.convert<String>(json['time_text']);
+  if (timeText != null) {
+    serviceTimePeriodEntity.timeText = timeText;
+  }
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    serviceTimePeriodEntity.time = time;
+  }
+  final bool? urgent = jsonConvert.convert<bool>(json['urgent']);
+  if (urgent != null) {
+    serviceTimePeriodEntity.urgent = urgent;
+  }
+  final bool? holiday = jsonConvert.convert<bool>(json['holiday']);
+  if (holiday != null) {
+    serviceTimePeriodEntity.holiday = holiday;
+  }
+  final bool? night = jsonConvert.convert<bool>(json['night']);
+  if (night != null) {
+    serviceTimePeriodEntity.night = night;
+  }
+  final bool? enable = jsonConvert.convert<bool>(json['enable']);
+  if (enable != null) {
+    serviceTimePeriodEntity.enable = enable;
+  }
+  return serviceTimePeriodEntity;
+}
+
+Map<String, dynamic> $ServiceTimePeriodEntityToJson(
+    ServiceTimePeriodEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time_text'] = entity.timeText;
+  data['time'] = entity.time;
+  data['urgent'] = entity.urgent;
+  data['holiday'] = entity.holiday;
+  data['night'] = entity.night;
+  data['enable'] = entity.enable;
+  return data;
+}
+
+extension ServiceTimePeriodEntityExtension on ServiceTimePeriodEntity {
+  ServiceTimePeriodEntity copyWith({
+    String? timeText,
+    String? time,
+    bool? urgent,
+    bool? holiday,
+    bool? night,
+    bool? enable,
+  }) {
+    return ServiceTimePeriodEntity()
+      ..timeText = timeText ?? this.timeText
+      ..time = time ?? this.time
+      ..urgent = urgent ?? this.urgent
+      ..holiday = holiday ?? this.holiday
+      ..night = night ?? this.night
+      ..enable = enable ?? this.enable;
+  }
+}

+ 2 - 0
packages/cs_plugin_basic/lib/constants/app_constant.dart

@@ -18,6 +18,8 @@ class AppConstant {
   static const storageDeviceUUID = 'storage_device_uuid'; //设备的UUID
   static const storageDarkModel = 'storage_dark_model'; //设备当前配置的模式
   static const storageGarageCategoryList = 'staorage_garage_category_list'; // 存储garage的分类列表
+  static const storagePaidServiceCategoryList = 'storage_paid_service_category_list'; // 存储paid service的分类列表
+  static const storageRepairServiceCategoryList = 'storage_repair_service_category_list'; // 存储paid service的分类列表
 
   //消息通知Key
   static const eventProfileRefresh = 'event_profile_refresh'; //通知用户信息需要刷新

+ 28 - 0
packages/cs_shared/lib/utils/richText_utils.dart

@@ -0,0 +1,28 @@
+//用于 flutter_html处理类似 '<img src="*****" style="width:100%;height:auto" />' 标签时渲染不出来,只要是由于 style 属性中有 width 或者 height属性 导致
+class RichtextUtils {
+  static String getHandleResult(String description) {
+    if (description ==null || description.isEmpty) {
+      return '';
+    }
+    String descriptionStr = description.replaceAllMapped(
+      RegExp(r'<img\s+([^>]*?)style="([^"]*?)"([^>]*)>'),
+          (match) {
+        // 获取原始的 <img> 标签部分
+        String imgTag = match.group(0)!;
+        // 获取 style 属性的内容
+        String style = match.group(2)!;
+        // 移除 style 中的 width 和 height
+        String newStyle = style.replaceAll(RegExp(r'\s*width:\s*\d+%;?'), '').replaceAll(RegExp(r'\s*height:\s*\d+%;?'), '').trim();
+        // 如果 style 为空,则移除整个 style 属性
+        if (newStyle.isEmpty) {
+          imgTag = imgTag.replaceAll(RegExp(r'\s+style="[^"]*?"'), '');
+        } else {
+          imgTag = imgTag.replaceAll(RegExp(r'style="[^"]*?"'), 'style="$newStyle"');
+        }
+        return imgTag;
+      },
+    );
+
+    return descriptionStr;
+  }
+}

+ 119 - 105
packages/cs_widgets/lib/dialog/dialog_content_wrap.dart

@@ -31,6 +31,7 @@ class DialogContentWrap extends StatefulWidget {
   VoidCallback? cancelAction;
   bool isShowConfirmBtn;
   bool isShowCancelBtn;
+  bool isConfirmAutoClose;
   Widget Function(BuildContext)? bottomFooterBuilder; // 自定义底部按钮区
   bool showCloseIcon;
   String? confirmTxt;
@@ -55,7 +56,6 @@ class DialogContentWrap extends StatefulWidget {
   final double? maxHeight;
   final double? dialogWidth;
 
-
   DialogContentWrap({
     Key? key,
     this.loadingState = LoadState.State_Loading,
@@ -69,6 +69,7 @@ class DialogContentWrap extends StatefulWidget {
     this.showCloseIcon = true,
     this.isShowConfirmBtn = true,
     this.isShowCancelBtn = true,
+    this.isConfirmAutoClose = true,
     this.confirmTxt,
     this.cancelTxt,
     this.titleTextStyle,
@@ -93,7 +94,7 @@ class DialogContentWrap extends StatefulWidget {
     dialogWidth,
   })
       : minHeight = minHeight ?? 0,
-        maxHeight = maxHeight ?? 300,
+        maxHeight = maxHeight ?? 500,
         dialogWidth = dialogWidth ?? 300.0,
         topLeftRadius = topLeftRadius ?? 0,
         topRightRadius = topRightRadius ?? 0,
@@ -164,115 +165,128 @@ class DialogContentWrapState extends State<DialogContentWrap> {
               errorMessage: _errorMessage,
               errorRetry: () {
               },
-              successWidget: Column(
-                children: [
-                  // 标题区
-                  Container(
-                     width: double.infinity,
-                      color: widget.titleBackgroundColor,
-                      child: Visibility(
-                        visible: _showTitleSection,
-                          child: (widget.title != null && widget.title!.isNotEmpty)? MyTextView(
-                            widget.title ?? '',
-                            fontSize: 18,
-                            isFontMedium: true,
-                            textColor: widget.titleTextStyle?.color ?? context.appColors.textBlack,
-                            paddingTop: 15,
-                            paddingBottom: 15,
-                            textAlign: TextAlign.center,
-                            textStyle: widget.titleTextStyle,
-                          ): widget.titleBuilder!.call(context),
-                      ),
-                  ),
-                  // 内容区
-                  Expanded(
-                    child: Scrollbar(
-                      child: ScrollConfiguration(
-                        behavior: NoShadowScrollBehavior(),
-                        child: SingleChildScrollView(
-                          child: Container(
-                            width: double.infinity,
-                            padding: widget.contentPadding,
-                            child: widget.messageBuilder?.call(context) ??
-                                MyTextView(
-                                  widget.message!,
-                                  fontSize: 18,
-                                  textColor: context.appColors.textBlack,
-                                  isFontRegular: true,
-                                  textAlign: TextAlign.center,
-                                ),
-                          ),
-                        ),
-                      ),
-                    ).constrained(maxHeight: _scrollMaxHeight),
-                  ),
-                  // 底部按钮区
-                  Visibility(
-                    visible: _showBottomBtnSection,
-                    child: (widget.isShowCancelBtn || widget.isShowConfirmBtn)? Container(
-                      height: _bottomBtnSectionHeight,
-                      color: context.appColors.whiteBG,
-                      padding: widget.bottomBtnSectionPadding,
-                      child: Row(
-                        mainAxisAlignment: MainAxisAlignment.center,
-                        children: [
-                          Visibility(
-                            visible: widget.isShowCancelBtn,
-                            child: Expanded(
-                                flex: 1,
-                                child: InkWell(
-                                  onTap: () {
-                                    onCancel();
-                                    widget.cancelAction?.call();
-                                  },
-                                  child: MyTextView(
-                                    widget.cancelTxt ?? S.current.no,
-                                    fontSize: 16,
+              successSliverWidget: [
+                SliverList(delegate: SliverChildBuilderDelegate(
+                    (context, index){
+                        return SizedBox(
+                          height: _scrollMaxHeight + _bottomBtnSectionHeight ,
+                          child: Column(
+                            children: [
+                              // 标题区
+                              Container(
+                                width: double.infinity,
+                                color: widget.titleBackgroundColor,
+                                child: Visibility(
+                                  visible: _showTitleSection,
+                                  child: (widget.title != null && widget.title!.isNotEmpty)? MyTextView(
+                                    widget.title ?? '',
+                                    fontSize: 18,
                                     isFontMedium: true,
-                                    paddingTop: 13,
-                                    paddingBottom: 13,
+                                    textColor: widget.titleTextStyle?.color ?? context.appColors.textBlack,
+                                    paddingTop: 15,
+                                    paddingBottom: 15,
                                     textAlign: TextAlign.center,
-                                    textColor: context.appColors.whiteBG,
-                                    backgroundColor: widget.noBtnBg ?? context.appColors.orangeBG,
-                                    cornerRadius: widget.bottomBtnRadius ?? 0,
-                                    textStyle: widget.noBtnTextStyle,
+                                    textStyle: widget.titleTextStyle,
+                                  ): widget.titleBuilder!.call(context),
+                                ),
+                              ),
+                              // 内容区
+                              Expanded(
+                                child: Scrollbar(
+                                  child: ScrollConfiguration(
+                                    behavior: NoShadowScrollBehavior(),
+                                    child: SingleChildScrollView(
+                                      child: Container(
+                                        width: double.infinity,
+                                        padding: widget.contentPadding,
+                                        child: widget.messageBuilder?.call(context) ??
+                                            MyTextView(
+                                              widget.message!,
+                                              fontSize: 18,
+                                              textColor: context.appColors.textBlack,
+                                              isFontRegular: true,
+                                              textAlign: TextAlign.center,
+                                            ),
+                                      ),
+                                    ),
                                   ),
-                                )),
-                          ),
-                          SizedBox(
-                            width: _bottomBtnMargin,
-                          ),
-                          Visibility(
-                            visible: widget.isShowConfirmBtn,
-                            child: Expanded(
-                                flex: 1,
-                                child: InkWell(
-                                  onTap: () async {
-                                    onCancel();
-                                    widget.confirmAction();
-                                  },
-                                  child: MyTextView(
-                                    widget.confirmTxt ?? S.current.yes,
-                                    fontSize: 16,
-                                    paddingTop: 13,
-                                    paddingBottom: 13,
-                                    isFontMedium: true,
-                                    textAlign: TextAlign.center,
-                                    textColor: Colors.white,
-                                    backgroundColor: widget.yesBtnBg?? context.appColors.btnBgDefault,
-                                    cornerRadius: widget.bottomBtnRadius ?? 0,
-                                    textStyle: widget.yesBtnTextStyle,
+                                ).constrained(maxHeight: _scrollMaxHeight),
+                              ),
+                              // 底部按钮区
+                              Visibility(
+                                visible: _showBottomBtnSection,
+                                child: (widget.isShowCancelBtn || widget.isShowConfirmBtn)? Container(
+                                  height: _bottomBtnSectionHeight,
+                                  color: context.appColors.whiteBG,
+                                  padding: widget.bottomBtnSectionPadding,
+                                  child: Row(
+                                    mainAxisAlignment: MainAxisAlignment.center,
+                                    children: [
+                                      Visibility(
+                                        visible: widget.isShowCancelBtn,
+                                        child: Expanded(
+                                            flex: 1,
+                                            child: InkWell(
+                                              onTap: () {
+                                                onCancel();
+                                                widget.cancelAction?.call();
+                                              },
+                                              child: MyTextView(
+                                                widget.cancelTxt ?? S.current.no,
+                                                fontSize: 16,
+                                                isFontMedium: true,
+                                                paddingTop: 13,
+                                                paddingBottom: 13,
+                                                textAlign: TextAlign.center,
+                                                textColor: context.appColors.whiteBG,
+                                                backgroundColor: widget.noBtnBg ?? context.appColors.orangeBG,
+                                                cornerRadius: widget.bottomBtnRadius ?? 0,
+                                                textStyle: widget.noBtnTextStyle,
+                                              ),
+                                            )),
+                                      ),
+                                      SizedBox(
+                                        width: _bottomBtnMargin,
+                                      ),
+                                      Visibility(
+                                        visible: widget.isShowConfirmBtn,
+                                        child: Expanded(
+                                            flex: 1,
+                                            child: InkWell(
+                                              onTap: () async {
+                                                if(widget.isConfirmAutoClose){
+                                                  onCancel();
+                                                }
+                                                widget.confirmAction();
+                                              },
+                                              child: MyTextView(
+                                                widget.confirmTxt ?? S.current.yes,
+                                                fontSize: 16,
+                                                paddingTop: 13,
+                                                paddingBottom: 13,
+                                                isFontMedium: true,
+                                                textAlign: TextAlign.center,
+                                                textColor: Colors.white,
+                                                backgroundColor: widget.yesBtnBg?? context.appColors.btnBgDefault,
+                                                cornerRadius: widget.bottomBtnRadius ?? 0,
+                                                textStyle: widget.yesBtnTextStyle,
+                                              ),
+                                            )),
+                                      ),
+                                    ],
                                   ),
-                                )),
+                                ): Container(
+                                  child: widget.bottomFooterBuilder?.call(context),
+                                ),
+                              ),
+                            ],
                           ),
-                        ],
-                      ),
-                    ): Container(
-                      child: widget.bottomFooterBuilder?.call(context),
+                        );
+                      },
+                    childCount: 1
                     ),
-                  ),
-                ],
-              ),
+                )
+              ]
             ),
           ),
         ),