Browse Source

inporgress列表
history列表
详情页面
取消逻辑与接口

liukai 1 month ago
parent
commit
7b3e5726dd
19 changed files with 1488 additions and 1167 deletions
  1. 150 165
      packages/cpt_services/lib/components/status_card_item.dart
  2. 1 1
      packages/cpt_services/lib/modules/services/clean_order_cancel_success/clean_order_cancel_success_page.dart
  3. 58 57
      packages/cpt_services/lib/modules/services/clean_order_detail/cancelOrderDialogContent.dart
  4. 120 121
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_page.dart
  5. 4 2
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_state.dart
  6. 78 224
      packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_vm.dart
  7. 21 27
      packages/cpt_services/lib/modules/services/history/history_page.dart
  8. 3 2
      packages/cpt_services/lib/modules/services/history/history_state.dart
  9. 35 159
      packages/cpt_services/lib/modules/services/history/history_vm.dart
  10. 21 32
      packages/cpt_services/lib/modules/services/inProgress/in_progress_page.dart
  11. 3 2
      packages/cpt_services/lib/modules/services/inProgress/in_progress_state.dart
  12. 35 161
      packages/cpt_services/lib/modules/services/inProgress/in_progress_vm.dart
  13. 151 167
      packages/cpt_services/lib/respository/services_respository.dart
  14. 75 0
      packages/cs_domain/lib/entity/garage_sale_history_entity.dart
  15. 47 47
      packages/cs_domain/lib/entity/garage_sale_rent_detail_entity.dart
  16. 141 0
      packages/cs_domain/lib/entity/service_order_detail_entity.dart
  17. 38 0
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  18. 176 0
      packages/cs_domain/lib/generated/json/garage_sale_history_entity.g.dart
  19. 331 0
      packages/cs_domain/lib/generated/json/service_order_detail_entity.g.dart

+ 150 - 165
packages/cpt_services/lib/components/status_card_item.dart

@@ -1,6 +1,7 @@
 import 'package:cpt_services/components/status_card_item_vm.dart';
 import 'package:cpt_services/modules/services/homeService/home_service_page.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -15,49 +16,33 @@ import 'package:widgets/my_text_view.dart';
 import '../constants_services.dart';
 
 class StausCardItem extends HookConsumerWidget {
-  int serviceId;
-  int serviceTypeCode;
-  int serviceStatusCode;
-  Map<String, dynamic> itemObj;
-  double? cardHeight ;
+  GarageSaleHistoryList? item;
+  double? cardHeight;
+
   final Function(dynamic)? onClickCard;
 
   StausCardItem({
     Key? key,
-    required this.serviceId,
-    required this.serviceTypeCode,
-    required this.serviceStatusCode,
-    required this.itemObj,
+    required this.item,
     this.onClickCard,
     cardHeight,
-  }): super(key: key) {
+  }) : super(key: key) {
     this.cardHeight = cardHeight ?? 180.0;
   }
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final vm = ref.read(statusCardItemVmProvider.notifier);
-
-    final title = itemObj.getValue("title", "House Cleaning Services");
-    final companyName = itemObj.getValue("company_name", "HONG YE GROUP PTE LTD");
-    final duration = itemObj.getValue("duration", "Daily cleaning for 2 hours");
-    final totalPrice = itemObj.getValue("totalPrice", '40');
-    final visit_time = itemObj.getValue("visit_time", '14 0ct 2024 15:00');
-    final order_time = itemObj.getValue("order_time", '13 0ct 2024 12:00');
-
-    Log.d("serviceStatusCode $serviceStatusCode");
-    String status_text = servicesConstants.servicesStatus['$serviceStatusCode']['text'];
-
-    // final status_text = itemObj.getValue("status_text", "");
+    // final vm = ref.read(statusCardItemVmProvider.notifier);
 
-    List<Map<String, dynamic>>? actionBtnList = servicesConstants.servicesStatusActionBtnList[serviceStatusCode];
+    // List<Map<String, dynamic>>? actionBtnList = servicesConstants.servicesStatusActionBtnList[serviceStatusCode];
     // Log.d("actionBtnList   $actionBtnList");
 
-    useEffect((){
-      vm.setInitData(context, serviceId, serviceTypeCode, serviceStatusCode);
-      return () {
-      };
-    },[]);
+    // useEffect((){
+    //   vm.setInitData(context, serviceId, serviceTypeCode, serviceStatusCode);
+    //   return () {
+    //   };
+    // },[]);
+
     return Container(
       width: double.infinity,
       height: cardHeight!,
@@ -67,116 +52,119 @@ class StausCardItem extends HookConsumerWidget {
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             Expanded(
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  // 标题 和状态
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      // 标题
-                      Expanded(
-                        child: MyTextView(
-                          title,
-                          fontSize: 16,
-                          maxLines: 1,
-                          isFontMedium: true,
-                          textAlign: TextAlign.left,
-                        ),
-                      ),
-                      // 状态
-                      MyTextView(
-                        status_text,
-                        fontSize: 14,
+                child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                // 标题 和状态
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    // 标题
+                    Expanded(
+                      child: MyTextView(
+                        item?.service?.name ?? "-",
+                        fontSize: 16,
                         maxLines: 1,
-                        isFontRegular: true,
+                        isFontMedium: true,
                         textAlign: TextAlign.left,
-                        textColor: context.appColors.textPrimary,
                       ),
-                    ],
-                  ),
-                  // 公司名称
-                  MyTextView(
-                    companyName,
-                    fontSize: 14,
-                    maxLines: 1,
-                    isFontRegular: true,
-                    textAlign: TextAlign.left,
-                    marginTop: 6,
-                  ),
-                  // 价格
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      // 公司名称
-                      MyTextView(
-                        duration,
-                        fontSize: 14,
-                        maxLines: 1,
-                        isFontRegular: true,
-                        textAlign: TextAlign.left,
-                      ),
-                      // 公司名称
-                      MyTextView(
-                        '\$$totalPrice',
-                        fontSize: 17,
-                        maxLines: 1,
-                        isFontBold: true,
-                        textAlign: TextAlign.left,
-                        textColor: context.appColors.textPrimary,
-                      ),
-                    ],
-                  ),
-                  SizedBox(height: 7.5,),
-                  // visit time
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      MyTextView(
-                        'Visit Time',
-                        fontSize: 14,
-                        maxLines: 1,
-                        isFontRegular: true,
-                        textAlign: TextAlign.left,
-                      ),
-                      MyTextView(
-                        visit_time,
-                        fontSize: 14,
-                        maxLines: 1,
-                        isFontRegular: true,
-                        textAlign: TextAlign.left,
-                        textColor: context.appColors.textBlack,
-                      ),
-                    ],
-                  ),
-                  SizedBox(height: 7.5,),
-                  // order time
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      MyTextView(
-                        'Order Time',
-                        fontSize: 14,
-                        maxLines: 1,
-                        isFontRegular: true,
-                        textAlign: TextAlign.left,
-                      ),
-                      MyTextView(
-                        order_time,
-                        fontSize: 14,
-                        maxLines: 1,
-                        isFontRegular: true,
-                        textAlign: TextAlign.left,
-                        textColor: context.appColors.textBlack,
-                      ),
-                    ],
-                  ),
-                ],
-              )
-            ),
+                    ),
+                    // 状态
+                    MyTextView(
+                      item?.orderStatus??"-",
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                      textColor: context.appColors.textPrimary,
+                    ),
+                  ],
+                ),
+                // 公司名称
+                MyTextView(
+                  item?.merchant?.name ?? "-",
+                  fontSize: 14,
+                  maxLines: 1,
+                  isFontRegular: true,
+                  textAlign: TextAlign.left,
+                  marginTop: 6,
+                ),
+                // 价格
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    // 商品/服务名称
+                    MyTextView(
+                      item?.orderProducts[0].productName ?? "-",
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                    ),
+                    // 公司名称
+                    MyTextView(
+                      '\$${item?.orderProducts[0].totalAmount ?? "-"}',
+                      fontSize: 17,
+                      maxLines: 1,
+                      isFontBold: true,
+                      textAlign: TextAlign.left,
+                      textColor: context.appColors.textPrimary,
+                    ),
+                  ],
+                ),
+                const SizedBox(
+                  height: 7.5,
+                ),
+                // visit time
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    MyTextView(
+                      'Visit Time',
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                    ),
+                    MyTextView(
+                      item?.orderProducts[0].plannedServiceAt ?? "-",
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                ),
+                const SizedBox(
+                  height: 7.5,
+                ),
+                // order time
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    MyTextView(
+                      'Order Time',
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                    ),
+                    MyTextView(
+                      item?.createdAt ?? "-",
+                      fontSize: 14,
+                      maxLines: 1,
+                      isFontRegular: true,
+                      textAlign: TextAlign.left,
+                      textColor: context.appColors.textBlack,
+                    ),
+                  ],
+                ),
+              ],
+            )),
             // Container(
-              // margin: EdgeInsets.only(top: 15),
-              // child: _buildActionSection(context,actionBtnList!, vm, ref),
+            // margin: EdgeInsets.only(top: 15),
+            // child: _buildActionSection(context,actionBtnList!, vm, ref),
             // ),
           ],
         ),
@@ -184,40 +172,37 @@ class StausCardItem extends HookConsumerWidget {
     );
   }
 
-  Widget _buildActionSection(BuildContext context,List<Map<String, dynamic>> actionBtnList, StatusCardItemVm vm, WidgetRef ref ) {
-    return LayoutBuilder(
-        builder: (BuildContext context, BoxConstraints constraints) {
-          final maxHeight = constraints.maxHeight;
-          final minHeight = constraints.minHeight;
-          final maxWidth = constraints.maxWidth;
-          // Log.d("---maxHeight-----$maxHeight-- $minHeight  $maxWidth--");
-          return Container(
-            height: 50,
-            // color: Colors.red,
-            width: maxWidth,
-            child: Row(
-              mainAxisAlignment: MainAxisAlignment.end,
-              mainAxisSize: MainAxisSize.max,
-              children: List.generate(actionBtnList.length, (index){
-                var item = actionBtnList[index];
-                // return Expanded(
-                //   child: _buildBtn(context, item),
-                // );
-                return _buildBtn(context, item, vm, ref);
-              })
-            ),
-          ).scrollable(
-            scrollDirection: Axis.horizontal,
-            physics: BouncingScrollPhysics(),
-          );
-      }
-    );
+  Widget _buildActionSection(BuildContext context, List<Map<String, dynamic>> actionBtnList, StatusCardItemVm vm, WidgetRef ref) {
+    return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
+      final maxHeight = constraints.maxHeight;
+      final minHeight = constraints.minHeight;
+      final maxWidth = constraints.maxWidth;
+      // Log.d("---maxHeight-----$maxHeight-- $minHeight  $maxWidth--");
+      return Container(
+        height: 50,
+        // color: Colors.red,
+        width: maxWidth,
+        child: Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            mainAxisSize: MainAxisSize.max,
+            children: List.generate(actionBtnList.length, (index) {
+              var item = actionBtnList[index];
+              // return Expanded(
+              //   child: _buildBtn(context, item),
+              // );
+              return _buildBtn(context, item, vm, ref);
+            })),
+      ).scrollable(
+        scrollDirection: Axis.horizontal,
+        physics: BouncingScrollPhysics(),
+      );
+    });
   }
 
   Widget _buildBtn(BuildContext context, Map<String, dynamic> btnItem, StatusCardItemVm vm, WidgetRef ref) {
     // final btnCode = btnItem['code'];
     return MyButton(
-      onPressed: (){
+      onPressed: () {
         vm.handlerClickActionBtn(context, btnItem);
       },
       text: btnItem['text'],
@@ -230,4 +215,4 @@ class StausCardItem extends HookConsumerWidget {
       minHeight: btnItem['btnHeight']?.toDouble() + 5,
     ).marginOnly(left: 5);
   }
-}
+}

+ 1 - 1
packages/cpt_services/lib/modules/services/clean_order_cancel_success/clean_order_cancel_success_page.dart

@@ -82,7 +82,7 @@ class CleanOrderCancelSuccessPage extends HookConsumerWidget {
                   text: "Back Home",
                   onPressed: (){
                     // 回到首页
-                    ComponentServiceManager().mainService.startMainPage();
+                    context.router.maybePop();
                   },
                   fontSize: 15,
                   fontWeight: FontWeight.w500,

+ 58 - 57
packages/cpt_services/lib/modules/services/clean_order_detail/cancelOrderDialogContent.dart

@@ -9,13 +9,16 @@ import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:shared/utils/color_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
 class CancelOrderDialogContent extends HookConsumerWidget {
+
   const CancelOrderDialogContent({
     Key? key,
   }) : super(key: key);
@@ -28,6 +31,7 @@ class CancelOrderDialogContent extends HookConsumerWidget {
       width: double.infinity,
       child: Column(
         mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
         children: [
           MyTextView(
             "Reason for canceling the order:",
@@ -60,66 +64,63 @@ class CancelOrderDialogContent extends HookConsumerWidget {
     );
   }
 
-
   /// 多行输入框
-  Widget _buildTextAreaLayout(BuildContext context, CleanOrderDetailVm vm, WidgetRef ref,String key){
+  Widget _buildTextAreaLayout(BuildContext context, CleanOrderDetailVm vm, WidgetRef ref, String key) {
     final state = ref.watch(cleanOrderDetailVmProvider);
     final noteCount = useState(0);
-    return Stack(
-        children: [
-          Container(
-            color: ColorUtils.string2Color("#F2F3F6"),
-            margin: const EdgeInsets.only(top: 15, bottom: 28.5),
-            padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
-            child: TextField(
-              cursorColor: context.appColors.authFiledText,
-              cursorWidth: 1.5,
-              autofocus: false,
-              enabled: true,
-              maxLines: null,
-              focusNode: state.cancelFormData![key]!['focusNode'],
-              controller: state.cancelFormData![key]!['controller'],
-              decoration: InputDecoration(
-                isDense: true,
-                isCollapsed: true,
-                border: InputBorder.none,
-                hintText: state.cancelFormData![key]!['hintText'],
-                hintStyle: TextStyle(
-                  color: context.appColors.authFiledHint,
-                  fontSize: 16.0,
-                  fontWeight: FontWeight.w400,
-                ),
-              ),
-              style: TextStyle(
-                color: context.appColors.authFiledText,
-                fontSize: 16.0,
-                fontWeight: FontWeight.w400,
-              ),
-              textInputAction: TextInputAction.done,
-              onSubmitted: (value) {
-                FocusScope.of(context).unfocus();
-              },
-              expands: true,
-              onChanged: (text) {
-                // 当文本改变时,更新字符数量
-                noteCount.value = text.length;
-                final cleanOrderDetailVm = ref.read(cleanOrderDetailVmProvider.notifier);
-                cleanOrderDetailVm.changeCancelFormData(context, text);
-              },
+    return Stack(children: [
+      Container(
+        color: ColorUtils.string2Color("#F2F3F6"),
+        margin: const EdgeInsets.only(top: 15, bottom: 28.5),
+        padding: const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
+        child: TextField(
+          cursorColor: context.appColors.authFiledText,
+          cursorWidth: 1.5,
+          autofocus: false,
+          enabled: true,
+          maxLines: null,
+          focusNode: state.cancelFormData![key]!['focusNode'],
+          controller: state.cancelFormData![key]!['controller'],
+          decoration: InputDecoration(
+            isDense: true,
+            isCollapsed: true,
+            border: InputBorder.none,
+            hintText: state.cancelFormData![key]!['hintText'],
+            hintStyle: TextStyle(
+              color: context.appColors.authFiledHint,
+              fontSize: 16.0,
+              fontWeight: FontWeight.w400,
             ),
           ),
-          // Positioned(
-          //   bottom: 0.0,
-          //   right: 0.0,
-          //   child: Text(
-          //     S.current.characters(noteCount.value),
-          //     style: TextStyle(
-          //       color: context.appColors.textBlack,
-          //       fontSize: 15.0,
-          //     ),
-          //   ),
-          // ),
-        ]
-    );
+          style: TextStyle(
+            color: context.appColors.authFiledText,
+            fontSize: 16.0,
+            fontWeight: FontWeight.w400,
+          ),
+          textInputAction: TextInputAction.done,
+          onSubmitted: (value) {
+            FocusScope.of(context).unfocus();
+          },
+          expands: true,
+          onChanged: (text) {
+            // 当文本改变时,更新字符数量
+            noteCount.value = text.length;
+            final cleanOrderDetailVm = ref.read(cleanOrderDetailVmProvider.notifier);
+            cleanOrderDetailVm.changeCancelFormData(context, text);
+          },
+        ),
+      ),
+      // Positioned(
+      //   bottom: 0.0,
+      //   right: 0.0,
+      //   child: Text(
+      //     S.current.characters(noteCount.value),
+      //     style: TextStyle(
+      //       color: context.appColors.textBlack,
+      //       fontSize: 15.0,
+      //     ),
+      //   ),
+      // ),
+    ]);
   }
-}
+}

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

@@ -3,6 +3,7 @@ import 'package:cpt_services/components/chooseAirConditionContent_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/service_order_detail_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/rendering.dart';
@@ -35,8 +36,9 @@ import '../../../components/status_card_item.dart';
 @RoutePage()
 class CleanOrderDetailPage extends HookConsumerWidget {
   final int id; // 订单id
-  final int serviceTypeCode;  // 订单类型
+  final int serviceTypeCode; // 订单类型
   final int serviesStatusCode; // 订单状态
+
   const CleanOrderDetailPage({
     Key? key,
     @PathParam('id') required this.id,
@@ -49,11 +51,10 @@ class CleanOrderDetailPage extends HookConsumerWidget {
     if (context != null) {
       context.router.push(CleanOrderDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode));
     } else {
-      appRouter.push(CleanOrderDetailPageRoute(id:id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode));
+      appRouter.push(CleanOrderDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode));
     }
   }
 
-
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(cleanOrderDetailVmProvider.notifier);
@@ -66,7 +67,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
     useEffect(() {
       vm.setInitPageData(id: id, serviceTypeCode: serviceTypeCode, serviceStatusCode: serviesStatusCode);
       // 组件挂载时执行 - 执行接口请求
-      Future.microtask(() => vm.initPageData());
+      Future.microtask(() => vm.fetchOrderDetailData(id));
       return () {
         // 组件卸载时执行
       };
@@ -93,27 +94,26 @@ class CleanOrderDetailPage extends HookConsumerWidget {
               state: state.loadingState,
               errorMessage: state.errorMessage,
               errorRetry: () {
-                vm.retryRequest();
+                vm.retryRequest(id);
               },
               successWidget: Column(
                 children: [
                   Expanded(
                     child: Padding(
                       padding: const EdgeInsets.only(bottom: 10),
-                      child: _buildBody(state, vm, context,ref),
+                      child: _buildBody(state, vm, context, ref),
                     ),
                   ),
                   // 底部联系信息
                   Visibility(
                     visible: state.loadingState == LoadState.State_Success,
-                    child: state.datas !=null ? _buildActionSection(context, state, vm, ref, id, serviceTypeCode,serviesStatusCode, actionBtnList): Container(),
+                    child:
+                        state.datas != null ? _buildActionSection(context, state, vm, ref, id, serviceTypeCode, serviesStatusCode, actionBtnList) : Container(),
                   )
-
                 ],
               ),
             ),
-          ).marginOnly(left: 0,right: 0,top: 0,bottom: 0)
-      ),
+          ).marginOnly(left: 0, right: 0, top: 0, bottom: 0)),
     );
   }
 
@@ -193,7 +193,6 @@ class CleanOrderDetailPage extends HookConsumerWidget {
   }
 
   Widget _buildOrderScore(CleanOrderDetailState state, CleanOrderDetailVm vm, BuildContext context) {
-    double score = 5.0;
     //  评分
     return Column(
       children: [
@@ -204,7 +203,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               MyTextView(
-                "House Cleaning Services",
+                state.datas?.orderService?.name ?? "-",
                 textColor: context.appColors.textBlack,
                 fontSize: 18,
                 isFontBold: true,
@@ -215,12 +214,13 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                 crossAxisAlignment: CrossAxisAlignment.center,
                 children: [
                   AnimatedRatingStars(
-                    initialRating: score,
-                    onChanged: (rating) {
-                    },
+                    initialRating: state.datas?.orderService?.evaluationsAvgScore ?? 0.0,
+                    onChanged: (rating) {},
                     readOnly: true,
-                    displayRatingValue: true, // Display the rating value
-                    interactiveTooltips: true, // Allow toggling half-star state
+                    displayRatingValue: true,
+                    // Display the rating value
+                    interactiveTooltips: true,
+                    // Allow toggling half-star state
                     customFilledIcon: Icons.star,
                     customHalfFilledIcon: Icons.star_half,
                     customEmptyIcon: Icons.star_border,
@@ -230,7 +230,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                     animationCurve: Curves.easeInOut,
                   ),
                   MyTextView(
-                    "${score}",
+                    "${state.datas?.orderService?.evaluationsAvgScore ?? 0.0}",
                     textColor: context.appColors.textBlack,
                     fontSize: 16,
                     isFontMedium: true,
@@ -239,7 +239,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                 ],
               ),
               MyTextView(
-                "HONG YE GROUP PTE LTD",
+                state.datas?.merchant?.name ?? "-",
                 textColor: context.appColors.textDarkGray999,
                 fontSize: 12,
                 isFontRegular: true,
@@ -272,7 +272,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 MyTextView(
-                  '705 Qiming Huijin Building',
+                  state.datas?.estateUnit?.address ?? "-",
                   fontSize: 17,
                   isFontBold: true,
                   textColor: context.appColors.textBlack,
@@ -282,13 +282,13 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                   mainAxisAlignment: MainAxisAlignment.start,
                   children: [
                     MyTextView(
-                      'Sundy',
+                      state.datas?.account?.name ?? "-",
                       fontSize: 14,
                       textColor: context.appColors.textDarkGray999,
                       isFontRegular: true,
                     ),
                     MyTextView(
-                      '+6588991122',
+                      "+${state.datas?.account?.phone ?? "-"}",
                       fontSize: 14,
                       textColor: context.appColors.textDarkGray999,
                       isFontRegular: true,
@@ -328,26 +328,36 @@ class CleanOrderDetailPage extends HookConsumerWidget {
             ),
           ],
         ),
-        if (serviceTypeCode == servicesConstants.servicesType['houseCleaning']!['code'])
-        // 室内清理
-          _buildCleanContent(context, state)
-        else if (serviceTypeCode == servicesConstants.servicesType['airConditioner']!['code'])
-        // 空调清理
-          _buildCleanContent(context, state)
+        
+        // if (serviceTypeCode == servicesConstants.servicesType['houseCleaning']!['code'])
+        //   // 室内清理
+        //   _buildCleanContent(context, state)
+        // else if (serviceTypeCode == servicesConstants.servicesType['airConditioner']!['code'])
+        //   // 空调清理
+        //   _buildCleanContent(context, state)
+        // else
+        //   const SizedBox.shrink()
+
+        // 根据 orderProducts 数组生成对应的 Widgets
+        if (state.datas?.orderProducts != null && state.datas!.orderProducts!.isNotEmpty)
+          ...state.datas!.orderProducts!.map((product) {
+            return _buildCleanContent(product, context);
+          }).toList()
         else
-          const SizedBox.shrink()
+          const SizedBox.shrink(), //空
+        
       ],
     );
   }
 
-  Widget _buildCleanContent(BuildContext context, state) {
-    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);
+  Widget _buildCleanContent(ServiceOrderDetailOrderProducts item ,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),
@@ -364,13 +374,13 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     MyTextView(
-                      title,
+                      item.productName?? '-',
                       fontSize: 16,
                       isFontMedium: true,
                       textColor: context.appColors.textBlack,
                     ),
                     MyTextView(
-                      areaSizeRange,
+                      "x${item.quantity}",
                       fontSize: 15,
                       isFontRegular: true,
                       textColor: context.appColors.textDarkGray999,
@@ -392,14 +402,14 @@ class CleanOrderDetailPage extends HookConsumerWidget {
               // )
               Container(
                 child: MyButton(
-                  text: '\$$price',
+                  text: '\$${item.totalAmount??""}',
                   onPressed: null,
                   minWidth: 80,
                   minHeight: 40,
                   fontSize: 19,
                   fontWeight: FontWeight.w500,
                   // enable: !isDisable.value,
-                  textColor:  context.appColors.textPrimary,
+                  textColor: context.appColors.textPrimary,
                   backgroundColor: context.appColors.textWhite,
                   disabledBackgroundColor: context.appColors.disEnableGray,
                   disabledTextColor: context.appColors.textWhite,
@@ -413,41 +423,33 @@ class CleanOrderDetailPage extends HookConsumerWidget {
     );
   }
 
-
   Widget _buildOrderTotalAmount(CleanOrderDetailState state, CleanOrderDetailVm vm, BuildContext context) {
-    return Column(
-      children: [
-        Row(
-          mainAxisAlignment: MainAxisAlignment.start,
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            const MyAssetImage(
-              Assets.serviceMoneyIcon,
-              width: 15,
-              height: 17.5,
-            ),
-            const SizedBox(
-             width: 10,
-            ),
-            MyTextView(
-              'Total Amount',
-              fontSize: 17,
-              isFontBold: true,
-              textColor: context.appColors.textBlack,
-            ),
-
-            MyTextView(
-              '\$200',
-              fontSize: 15,
-              textColor: context.appColors.textBlack,
-              isFontBold: true,
-              textAlign: TextAlign.end,
-              marginRight: 17,
-            ).expanded(),
-          ]
-        )
-      ]
-    );
+    return Column(children: [
+      Row(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
+        const MyAssetImage(
+          Assets.serviceMoneyIcon,
+          width: 15,
+          height: 17.5,
+        ),
+        const SizedBox(
+          width: 10,
+        ),
+        MyTextView(
+          'Total Amount',
+          fontSize: 17,
+          isFontBold: true,
+          textColor: context.appColors.textBlack,
+        ),
+        MyTextView(
+          '\$${state.datas?.totalAmount ?? 0}',
+          fontSize: 15,
+          textColor: context.appColors.textBlack,
+          isFontBold: true,
+          textAlign: TextAlign.end,
+          marginRight: 17,
+        ).expanded(),
+      ])
+    ]);
   }
 
   Widget _buildOrderVisitTime(CleanOrderDetailState state, CleanOrderDetailVm vm, BuildContext context) {
@@ -481,7 +483,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
             mainAxisAlignment: MainAxisAlignment.end,
             children: [
               MyTextView(
-                '2021-01-01 12:00',
+                state.datas?.orderProducts?[0].plannedServiceAt ?? '',
                 fontSize: 15,
                 textColor: context.appColors.textDarkGray999,
                 isFontRegular: true,
@@ -537,7 +539,7 @@ class CleanOrderDetailPage extends HookConsumerWidget {
                 ],
               ),
               MyButton(
-                onPressed: (){
+                onPressed: () {
                   ComponentServiceManager().paymentService.startChooseCardPage();
                 },
                 text: 'Change',
@@ -582,23 +584,23 @@ class CleanOrderDetailPage extends HookConsumerWidget {
           ],
         ),
         Container(
-          margin: const EdgeInsets.only(left:10, right:10,top: 0),
+          margin: const EdgeInsets.only(left: 10, right: 10, top: 0),
           width: double.infinity,
           padding: const EdgeInsets.all(15),
           decoration: BoxDecoration(
-              color: ColorUtils.string2Color("#F8F8F8"),
-              borderRadius: BorderRadius.circular(5),
-              // boxShadow: [
-              //   BoxShadow(
-              //     color: Colors.grey.withOpacity(0.2),
-              //     spreadRadius:1,
-              //     blurRadius: 2,
-              //     offset: const Offset(0.5, 0.5), // changes position of shadow
-              //   ),
-              // ]
+            color: ColorUtils.string2Color("#F8F8F8"),
+            borderRadius: BorderRadius.circular(5),
+            // boxShadow: [
+            //   BoxShadow(
+            //     color: Colors.grey.withOpacity(0.2),
+            //     spreadRadius:1,
+            //     blurRadius: 2,
+            //     offset: const Offset(0.5, 0.5), // changes position of shadow
+            //   ),
+            // ]
           ),
           child: MyTextView(
-            'Hope to arrive as soon as possible',
+            state.datas?.notes ?? "",
             fontSize: 16,
             isFontRegular: true,
             textColor: context.appColors.textBlack,
@@ -609,7 +611,6 @@ class CleanOrderDetailPage extends HookConsumerWidget {
     );
   }
 
-
   Widget _buildOrderRules(CleanOrderDetailState state, CleanOrderDetailVm vm, BuildContext context) {
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
@@ -643,41 +644,39 @@ class CleanOrderDetailPage extends HookConsumerWidget {
   }
 
   // 底部操作区域
-  Widget _buildActionSection(BuildContext context,state, vm ,WidgetRef ref, int id, int serviceTypeCode, int serviesStatusCode, List<Map<String, dynamic>> actionBtnList) {
-    return LayoutBuilder(
-        builder: (BuildContext context, BoxConstraints constraints) {
-          final maxHeight = constraints.maxHeight;
-          final minHeight = constraints.minHeight;
-          final maxWidth = constraints.maxWidth;
-          // Log.d("---maxHeight-----$maxHeight-- $minHeight  $maxWidth--");
-          return Container(
-            height: 71.5,
-            color: context.appColors.whiteBG,
-            width: maxWidth,
-            padding: const EdgeInsets.only(left: 10, right: 10),
-            child: Row(
-                mainAxisAlignment: MainAxisAlignment.center,
-                mainAxisSize: MainAxisSize.max,
-                children: List.generate(actionBtnList.length, (index){
-                  var item = actionBtnList[index];
-                  return Expanded(
-                    child: _buildBtn(context, item, vm, ref),
-                  );
-                  // return _buildBtn(context, item, vm, ref);
-                })
-            ),
-          ).scrollable(
-            scrollDirection: Axis.horizontal,
-            physics: BouncingScrollPhysics(),
-          );
-        }
-    );
+  Widget _buildActionSection(
+      BuildContext context, state, vm, WidgetRef ref, int id, int serviceTypeCode, int serviesStatusCode, List<Map<String, dynamic>> actionBtnList) {
+    return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
+      final maxHeight = constraints.maxHeight;
+      final minHeight = constraints.minHeight;
+      final maxWidth = constraints.maxWidth;
+      // Log.d("---maxHeight-----$maxHeight-- $minHeight  $maxWidth--");
+      return Container(
+        height: 71.5,
+        color: context.appColors.whiteBG,
+        width: maxWidth,
+        padding: const EdgeInsets.only(left: 10, right: 10),
+        child: Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            mainAxisSize: MainAxisSize.max,
+            children: List.generate(actionBtnList.length, (index) {
+              var item = actionBtnList[index];
+              return Expanded(
+                child: _buildBtn(context, item, vm, ref),
+              );
+              // return _buildBtn(context, item, vm, ref);
+            })),
+      ).scrollable(
+        scrollDirection: Axis.horizontal,
+        physics: BouncingScrollPhysics(),
+      );
+    });
   }
 
   Widget _buildBtn(BuildContext context, Map<String, dynamic> btnItem, vm, WidgetRef ref) {
     // final btnCode = btnItem['code'];
     return MyButton(
-      onPressed: (){
+      onPressed: () {
         vm.handlerClickActionBtn(context, btnItem);
       },
       text: btnItem['text'],
@@ -690,4 +689,4 @@ class CleanOrderDetailPage extends HookConsumerWidget {
       minHeight: btnItem['btnHeight']?.toDouble() + 5,
     ).marginOnly(left: 5);
   }
-}
+}

+ 4 - 2
packages/cpt_services/lib/modules/services/clean_order_detail/clean_order_detail_state.dart

@@ -1,3 +1,4 @@
+import 'package:domain/entity/service_order_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:widgets/load_state_layout.dart';
 
@@ -6,7 +7,8 @@ class CleanOrderDetailState {
   LoadState loadingState;
   String? errorMessage;
   double? totalPrice;
-  Map<String, dynamic>? datas;
+
+  ServiceOrderDetailEntity? datas;
 
   String? cancelReason;  // 取消的文字
 
@@ -36,7 +38,7 @@ class CleanOrderDetailState {
     double? totalPrice,
     String? cancelReason,
     Map<String, Map<String, dynamic>>? cancelFormData,
-    Map<String, dynamic>? datas,
+    ServiceOrderDetailEntity? datas,
   }) {
     return CleanOrderDetailState(
       loadingState: loadingState ?? this.loadingState,

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

@@ -1,4 +1,3 @@
-
 import 'package:cpt_services/components/chooseAirConditionContent_vm.dart';
 import 'package:cpt_services/components/chooseHouseCleanContent_vm.dart';
 import 'package:cpt_services/components/chooseVisitTimeContent.dart';
@@ -12,10 +11,12 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.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:shared/utils/util.dart';
 import 'package:widgets/dialog/app_custom_dialog.dart';
 import 'package:widgets/dialog/app_default_dialog.dart';
 import 'package:widgets/dialog/dialog_content_wrap.dart';
@@ -36,16 +37,10 @@ import 'clean_order_detail_state.dart';
 
 part 'clean_order_detail_vm.g.dart';
 
-
-final _chooseVisitTimeDialogGlobalKey = GlobalKey<DialogContentWrapState>();
-
 @riverpod
-class CleanOrderDetailVm extends _$CleanOrderDetailVm {
+class CleanOrderDetailVm extends _$CleanOrderDetailVm with DioCancelableMixin {
   late ServicesRespository servicesRespositoryInstance;
   bool _needShowPlaceholder = false; //是否展示LoadingView
-  int _page = 1;  // 当前页
-  int _limit = 10; // 每页数量
-  int _count = 0; // 总条数
 
   late int _detailId;
   late int _detailServiceTypeCode;
@@ -53,23 +48,22 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   CleanOrderDetailState initState() {
     return CleanOrderDetailState(
-        datas: {}
+      datas: null,
     );
   }
 
   @override
-  CleanOrderDetailState build(){
-    // 引入数据仓库
-    // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
+  CleanOrderDetailState build() {
+    servicesRespositoryInstance = ref.read(servicesRespositoryProvider);
     final state = initState();
     Log.d("--------------------------build---------------------");
-    // 处理 remarkInfo 数据的回显
+    registerCancellation();
     this.onInit();
     return state;
   }
@@ -80,198 +74,31 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
 
   //刷新页面状态
   void changeLoadingState(LoadState loadState, String? errorMsg) {
-    state = state.copyWith(
-        loadingState: loadState,
-        errorMessage: errorMsg
-    );
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
   }
 
-  setInitPageData({required int id, required int serviceTypeCode, required int serviceStatusCode}){
+  setInitPageData({required int id, required int serviceTypeCode, required int serviceStatusCode}) {
     _detailId = id;
     _detailServiceTypeCode = serviceTypeCode;
     _detailServiceStatusCode = serviceStatusCode;
   }
 
   // 初始化页面数据
-  initPageData({detailId, detailServiceTypeCode, detailServiceStatusCode}) {
-    _detailId = detailId??_detailId;
-    _detailServiceTypeCode = detailServiceTypeCode??_detailServiceTypeCode;
-    _detailServiceStatusCode = detailServiceStatusCode??_detailServiceStatusCode;
-    Log.d("--------------------------initPageData---------------------");
-    changeLoadingState(LoadState.State_Success, null);
-  }
-
-  // 上拉加载 更多
-  Future loadMore() async {
-    Log.d("----home_service_vm-----loadMore");
-    _page++;
-    getListData();
-  }
-
-  // 下拉刷新
-  Future onRefresh() async {
-    // 当前pageView 页面正处于显示状态
-    Log.d("----forsale_vm-----onRefresh ");
-    // await Future.delayed(const Duration(seconds: 2));
-    _page = 1;
-    getListData();
-  }
-
-
-  // 手动进行刷新
-  Future triggerRefresh() async {
-    Log.d("trggerRefresh");
-    refreshController.callRefresh();
-  }
-
-  // 手动进行刷新
-  Future directRefresh() async {
-    state = state.copyWith(datas:null);
-    // 注意:由于 nestedscrollview 嵌套easyfresh 组件  refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口
-    // https://github.com/xuelongqy/flutter_easy_refresh/issues/692
-    refreshController.callRefresh();
-    refreshController.resetFooter();
-    _page = 1;
-    _needShowPlaceholder = true;
-    getListData();
-  }
-
+  // initPageData({detailId, detailServiceTypeCode, detailServiceStatusCode}) {
+  //   _detailId = detailId??_detailId;
+  //   _detailServiceTypeCode = detailServiceTypeCode??_detailServiceTypeCode;
+  //   _detailServiceStatusCode = detailServiceStatusCode??_detailServiceStatusCode;
+  //   Log.d("--------------------------initPageData---------------------");
+  //   changeLoadingState(LoadState.State_Success, null);
+  // }
 
   // 重试请求
-  Future retryRequest() async {
-    _page = 1;
+  Future retryRequest(int id) async {
     _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;
-
+    fetchOrderDetailData(id);
   }
 
-  handlerResultData(bool isList, {List<Map<String, dynamic>>? list, dynamic? data}){
-    Future.delayed(const Duration(seconds: 1)).then((value) {
-      if(isList){
-        // list 数据模式
-        // if(list != null && list.isNotEmpty){
-        //   if(_page == 1){
-        //     state.list.clear();
-        //     state.list!.addAll(list);
-        //     refreshController.finishRefresh();
-        //     changeLoadingState(LoadState.State_Success, null);
-        //   }else {
-        //     final allList = state.list;
-        //     allList!.addAll(list);
-        //     state = state.copyWith(list: allList);
-        //     refreshController.finishLoad();
-        //   }
-        // }else {
-        //   if(_page == 1){
-        //     state.list.clear();
-        //     changeLoadingState(LoadState.State_Empty, null);
-        //     refreshController.finishRefresh();
-        //   }else {
-        //     refreshController.finishLoad(IndicatorResult.noMore);
-        //   }
-        // }
-      }else {
-        // 单个数据模式
-        if(data!=null){
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Success, null);
-        }else {
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Empty, null);
-        }
-      }
-    });
-  }
-
-  handlerClickActionBtn(BuildContext context, Map<String, dynamic> actionBtn){
+  handlerClickActionBtn(BuildContext context, Map<String, dynamic> actionBtn) {
     final actionBtnCode = actionBtn['code']!.toString();
     switch (actionBtnCode) {
       case '0':
@@ -292,25 +119,26 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
         break;
       case '4':
         // Evaluate 去评价
-        ServiceEvaluateCreatePage.startInstance(id: _detailId, serviceTypeCode: _detailServiceTypeCode,);
+        ServiceEvaluateCreatePage.startInstance(
+          id: _detailId,
+          serviceTypeCode: _detailServiceTypeCode,
+        );
         break;
       default:
         break;
     }
   }
 
-  handlerDeleteOrder(BuildContext context){
+  handlerDeleteOrder(BuildContext context) {
     DialogEngine.show(
-      widget: AppCustomDialog(
-        message: "Are you sure you want to delete?",
-        confirmAction: () {
-        },
-      )
-    );
+        widget: AppCustomDialog(
+      message: "Are you sure you want to delete?",
+      confirmAction: () {},
+    ));
   }
 
   // 取消订单
-  handlerCancelOrder(BuildContext context){
+  handlerCancelOrder(BuildContext context) {
     DialogEngine.show(
         tag: "cancelOrder",
         position: DialogPosition.center,
@@ -328,13 +156,13 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
             color: context.appColors.textWhite,
           ),
           messageBuilder: (context) {
-            return CancelOrderDialogContent();
+            return const CancelOrderDialogContent();
           },
-          bottomFooterBuilder: (context){
+          bottomFooterBuilder: (context) {
             return Padding(
-              padding: const EdgeInsets.only( bottom: 40),
+              padding: const EdgeInsets.only(bottom: 40),
               child: MyButton(
-                onPressed: (){
+                onPressed: () {
                   // 提交取消订单
                   submitCancelOrder(context);
                 },
@@ -354,8 +182,8 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
           topRightRadius: 10.0,
           bottomLeftRadius: 10.0,
           bottomRightRadius: 10.0,
-          contentPadding: const EdgeInsets.only(left: 20, right: 20, bottom: 20,top: 20),
-          bottomBtnSectionPadding: const EdgeInsets.only(left: 20, right: 20, bottom: 20,top: 20),
+          contentPadding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 20),
+          bottomBtnSectionPadding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 20),
           cancelAction: () {
             DialogEngine.dismiss(tag: 'cancelOrder');
             clearReasonInput();
@@ -363,27 +191,53 @@ class CleanOrderDetailVm extends _$CleanOrderDetailVm {
           confirmAction: () {
             clearReasonInput();
           },
-        )
-    );
+        ));
   }
 
-  changeCancelFormData(BuildContext context,String cancelReason){
-    state.cancelReason = cancelReason;
-    // state = state.copyWith(
-    //   cancelReason: cancelReason
-    // );
+  changeCancelFormData(BuildContext context, String cancelReason) {
+    // state.cancelReason = cancelReason;
+    state = state.copyWith(cancelReason: cancelReason);
   }
 
-  submitCancelOrder(BuildContext context){
-    Log.d("cancelReason:  ${state.cancelReason}");
-    clearReasonInput();
-    DialogEngine.dismiss(tag: 'cancelOrder');
-    // 去成功页面
-    CleanOrderCancelSuccessPage.startInstance();
+  submitCancelOrder(BuildContext context) async {
+    Log.d("cancelReason: ${state.cancelReason}");
+
+    if (Utils.isNotEmpty(state.cancelReason)) {
+      //调用接口取消订单
+      DialogEngine.dismiss(tag: 'cancelOrder');
+
+      final result = await servicesRespositoryInstance.fetchCancelPaidServiceOrder(id: _detailId.toString(), reason: state.cancelReason);
+
+      if (result.isSuccess) {
+        clearReasonInput();
+        //去成功页面
+        CleanOrderCancelSuccessPage.startInstance();
+      } else {
+        ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+      }
+    } else {
+      ToastEngine.show("Please enter the reason for cancellation");
+    }
   }
 
-  clearReasonInput(){
+  clearReasonInput() {
     state.cancelReason = "";
     state.cancelFormData!['reason']!["controller"].text = "";
   }
-}
+
+  //获取详情数据
+  fetchOrderDetailData(int id) async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading, null);
+    }
+
+    final result = await servicesRespositoryInstance.fetchPaidServiceCleanOrderDetail(id: id.toString(), cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      state = state.copyWith(datas: result.data);
+      changeLoadingState(LoadState.State_Success, null);
+    } else {
+      changeLoadingState(LoadState.State_Error, result.errorMsg ?? "UnKnow Error");
+    }
+  }
+}

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

@@ -1,4 +1,5 @@
 import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
@@ -38,7 +39,6 @@ class HistoryPage extends HookConsumerWidget {
     }
   }
 
-
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(historyVmProvider.notifier);
@@ -48,7 +48,6 @@ class HistoryPage extends HookConsumerWidget {
     int serviceTypeCode = servicesConstants.servicesType['houseCleaning']?['code'];
     int serviceStatusCode = servicesConstants.servicesStatus['2']?['code'];
 
-
     useEffect(() {
       // 组件挂载时执行 - 执行接口请求
       Future.microtask(() => vm.initPageData());
@@ -72,12 +71,12 @@ class HistoryPage extends HookConsumerWidget {
             key: ValueKey('history'),
             controller: vm.refreshController,
             // 上拉加载
-            onLoad: () async{
+            onLoad: () async {
               Log.d("----onLoad");
               vm.loadMore();
             },
             // 下拉刷新
-            onRefresh: () async{
+            onRefresh: () async {
               Log.d("----onRefresh");
               vm.onRefresh();
             },
@@ -87,23 +86,23 @@ class HistoryPage extends HookConsumerWidget {
               errorRetry: () {
                 vm.retryRequest();
               },
-              successSliverWidget:[
+              successSliverWidget: [
                 SliverList(
                   delegate: SliverChildBuilderDelegate(
-                        (context, index) {
-                      return  _buildHistoryItem(
-                          context,
-                          ref,
-                          state.list[index],
-                          vm,
-                          serviceTypeCode,
-                          serviceStatusCode,
-                      ).onTap((){
+                    (context, index) {
+                      return _buildHistoryItem(
+                        context,
+                        ref,
+                        state.list[index],
+                        vm,
+                        serviceTypeCode,
+                        serviceStatusCode,
+                      ).onTap(() {
                         vm.gotoCleanOrderDetailPage(
                           context,
-                          state.list?[index]['id'],
-                          serviceTypeCode,
-                          serviceStatusCode,
+                          state.list[index].id != null ? int.tryParse(state.list[index].id!) ?? 0 : 0,
+                          0,
+                          0,
                         );
                       });
                     },
@@ -112,12 +111,11 @@ class HistoryPage extends HookConsumerWidget {
                 )
               ],
             ),
-          ).marginOnly(left: 15,right: 15,top: 0,bottom: 15)
-      ),
+          ).marginOnly(left: 15, right: 15, top: 0, bottom: 15)),
     );
   }
 
-  Widget _buildHistoryItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, int serviceTypeCode, int serviceStatusCode){
+  Widget _buildHistoryItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, int serviceTypeCode, int serviceStatusCode) {
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,
@@ -135,13 +133,9 @@ class HistoryPage extends HookConsumerWidget {
       child: StausCardItem(
         key: UniqueKey(),
         cardHeight: 175.0,
-        serviceId: item['id'],
-        serviceTypeCode: serviceTypeCode,
-        serviceStatusCode: serviceStatusCode,
-        itemObj: item.cast<String, dynamic>(),
-        onClickCard: (dynamic value) async {
-        },
+        item: item,
+        onClickCard: (dynamic value) async {},
       ),
     );
   }
-}
+}

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

@@ -1,3 +1,4 @@
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class HistoryState {
@@ -7,7 +8,7 @@ class HistoryState {
 
   String? keyword;
   bool? isLiked;
-  List<Map<String, dynamic>> list;
+  List<GarageSaleHistoryList> list;
 
 
   HistoryState({
@@ -25,7 +26,7 @@ class HistoryState {
     bool? isLiked,
     Map<String, dynamic>? activeSortMap,
     List<Map<String, dynamic>>? activeCateGoryList,
-    List<Map<String, dynamic>>? list,
+    List<GarageSaleHistoryList>? list,
   }) {
     return HistoryState(
       loadingState: loadingState ?? this.loadingState,

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

@@ -1,9 +1,11 @@
 
 import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/newsfeed_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -18,10 +20,10 @@ import 'history_state.dart';
 part 'history_vm.g.dart';
 
 @riverpod
-class HistoryVm extends _$HistoryVm {
+class HistoryVm extends _$HistoryVm with DioCancelableMixin{
   late ServicesRespository servicesRespositoryInstance;
   bool _needShowPlaceholder = false; //是否展示LoadingView
-  int _page = 1;  // 当前页
+  int _page = 1; // 当前页
   int _limit = 10; // 每页数量
   int _count = 0; // 总条数
 
@@ -33,8 +35,8 @@ class HistoryVm extends _$HistoryVm {
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   HistoryState initState() {
@@ -44,22 +46,20 @@ class HistoryVm extends _$HistoryVm {
   }
 
   @override
-  HistoryState build(){
+  HistoryState build() {
+    servicesRespositoryInstance = ref.read(servicesRespositoryProvider);
     // 引入数据仓库
     // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
     final state = initState();
     Log.d("--------------------------build---------------------");
+    registerCancellation();
 
     return state;
   }
 
-
   //刷新页面状态
   void changeLoadingState(LoadState loadState, String? errorMsg) {
-    state = state.copyWith(
-        loadingState: loadState,
-        errorMessage: errorMsg
-    );
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
   }
 
   // 初始化页面数据
@@ -75,7 +75,6 @@ class HistoryVm extends _$HistoryVm {
     getListData();
   }
 
-
   // 下拉刷新
   Future onRefresh() async {
     // 当前pageView 页面正处于显示状态
@@ -85,7 +84,6 @@ class HistoryVm extends _$HistoryVm {
     getListData();
   }
 
-
   // 手动进行刷新
   Future triggerRefresh() async {
     Log.d("trggerRefresh");
@@ -94,7 +92,7 @@ class HistoryVm extends _$HistoryVm {
 
   // 手动进行刷新
   Future directRefresh() async {
-    state = state.copyWith(list:[]);
+    state = state.copyWith(list: []);
     // 注意:由于 nestedscrollview 嵌套easyfresh 组件  refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口
     // https://github.com/xuelongqy/flutter_easy_refresh/issues/692
     refreshController.callRefresh();
@@ -104,7 +102,6 @@ class HistoryVm extends _$HistoryVm {
     getListData();
   }
 
-
   // 重试请求
   Future retryRequest() async {
     _page = 1;
@@ -112,195 +109,74 @@ class HistoryVm extends _$HistoryVm {
     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': 2,
-        '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': 2,
-        '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': 3,
-        'company_name': 'HONG YE GROUP PTE LTD',
-      },
-    ];
-    handlerResultData(true, list:list);
+    // 获取列表
+    var listResult = await servicesRespositoryInstance.fetchPaidServiceOrderList(
+      type: "history",
+      curPage: _page,
+      cancelToken: cancelToken,
+    );
 
-    // 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");
-    // }
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
+    }
 
     // 最后赋值
     _needShowPlaceholder = false;
-
   }
 
-  handlerResultData(bool isList, {List<Map<String, dynamic>>? list, dynamic? data}){
-    Future.delayed(const Duration(seconds: 1)).then((value) {
-      if(isList){
-        // list 数据模式
-        if(list != null && list.isNotEmpty){
-          if(_page == 1){
-            state.list.clear();
-            state.list!.addAll(list);
-            refreshController.finishRefresh();
-            changeLoadingState(LoadState.State_Success, null);
-          }else {
-            final allList = state.list;
-            allList!.addAll(list);
-            state = state.copyWith(list: allList);
-            refreshController.finishLoad();
-          }
-        }else {
-          if(_page == 1){
-            state.list.clear();
-            changeLoadingState(LoadState.State_Empty, null);
-            refreshController.finishRefresh();
-          }else {
-            refreshController.finishLoad(IndicatorResult.noMore);
-          }
-        }
-      }else {
-        // 单个数据模式
-        if(data!=null){
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Success, null);
-        }else {
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Empty, null);
-        }
-      }
-    });
-  }
-
-  void handlerResultList(List<GarageSaleRentList>? list, bool isLoadMore) {
+  // 处理数据与展示的逻辑
+  void handleList(List<GarageSaleHistoryList>? list) {
     if (list != null && list.isNotEmpty) {
       //有数据,判断是刷新还是加载更多的数据
       if (_page == 1) {
         //刷新的方式
-        state.list!.clear();
-        state.list!.addAll(list.map((item) => item.toJson()).toList());
+        state = state.copyWith(list: list);
         refreshController.finishRefresh();
+
         //更新展示的状态
         changeLoadingState(LoadState.State_Success, null);
       } else {
         //加载更多
-        final allList = state.list;
-        allList!.addAll(list.map((item) => item.toJson()).toList());
-        state = state.copyWith(list: allList);
+        state.list.addAll(List<GarageSaleHistoryList>.from(state.list)..addAll(list));
         refreshController.finishLoad();
       }
     } else {
       if (_page == 1) {
         //展示无数据的布局
-        state.list!.clear();
+        state = state.copyWith(list: []);
         changeLoadingState(LoadState.State_Empty, null);
         refreshController.finishRefresh();
       } else {
         //展示加载完成,没有更多数据了
-        if (_page == 1) {
-          //展示无数据的布局
-          state.list!.clear();
-          changeLoadingState(LoadState.State_Empty, null);
-          refreshController.finishRefresh();
-        } else {
-          //展示加载完成,没有更多数据了
-          if(state.list!.length == 0){
-            changeLoadingState(LoadState.State_Empty, null);
-            refreshController.finishLoad();
-          }else {
-            if(_needShowPlaceholder){
-              changeLoadingState(LoadState.State_Success, null);
-            }
-          }
-          //更新展示的状态
-          refreshController.finishLoad(IndicatorResult.noMore);
-        }
+        refreshController.finishLoad(IndicatorResult.noMore);
       }
     }
   }
 
   // 设置当前的 _queryParams
-  setCurrentQueryParams(Map<String, dynamic> params){
+  setCurrentQueryParams(Map<String, dynamic> params) {
     _queryParams.addAll(params);
   }
 
   // 获取当前的 _queryParams
-  Map<String, dynamic> getCurrentQueryParams(String? key){
-    if(key!=null && key!.isNotEmpty){
+  Map<String, dynamic> getCurrentQueryParams(String? key) {
+    if (key != null && key!.isNotEmpty) {
       return _queryParams[key];
     }
     return _queryParams;
   }
 
-  // 去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode){
+  //  去详情页面
+  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode) {
     CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
   }
 }

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

@@ -1,4 +1,5 @@
 import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
@@ -38,7 +39,6 @@ class InProgressPage extends HookConsumerWidget {
     }
   }
 
-
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final vm = ref.read(inProgressVmProvider.notifier);
@@ -71,12 +71,12 @@ class InProgressPage extends HookConsumerWidget {
             key: ValueKey('inProgress'),
             controller: vm.refreshController,
             // 上拉加载
-            onLoad: () async{
+            onLoad: () async {
               Log.d("----onLoad");
               vm.loadMore();
             },
             // 下拉刷新
-            onRefresh: () async{
+            onRefresh: () async {
               Log.d("----onRefresh");
               vm.onRefresh();
             },
@@ -86,23 +86,16 @@ class InProgressPage extends HookConsumerWidget {
               errorRetry: () {
                 vm.retryRequest();
               },
-              successSliverWidget:[
+              successSliverWidget: [
                 SliverList(
                   delegate: SliverChildBuilderDelegate(
-                        (context, index) {
-                      return  _buildInProgressItem(
-                          context,
-                          ref,
-                          state.list[index],
-                          vm,
-                          serviceTypeCode,
-                          serviceStatusCode
-                      ).onTap((){
+                    (context, index) {
+                      return _buildInProgressItem(context, ref, state.list[index], vm, serviceTypeCode, serviceStatusCode).onTap(() {
                         vm.gotoCleanOrderDetailPage(
-                            context,
-                            state.list?[index]['id'],
-                            serviceTypeCode,
-                            serviceStatusCode
+                          context,
+                          state.list[index].id != null ? int.tryParse(state.list[index].id!) ?? 0 : 0,
+                          0,
+                          0,
                         );
                       });
                     },
@@ -111,12 +104,11 @@ class InProgressPage extends HookConsumerWidget {
                 )
               ],
             ),
-          ).marginOnly(left: 15,right: 15,top: 0,bottom: 15)
-      ),
+          ).marginOnly(left: 15, right: 15, top: 0, bottom: 15)),
     );
   }
 
-  Widget _buildInProgressItem(BuildContext context, WidgetRef ref, Map<String, dynamic> item, vm, int serviceTypeCode, int serviceStatusCode){
+  Widget _buildInProgressItem(BuildContext context, WidgetRef ref, GarageSaleHistoryList item, vm, int serviceTypeCode, int serviceStatusCode) {
     return Container(
       margin: const EdgeInsets.only(top: 9),
       width: double.infinity,
@@ -132,18 +124,15 @@ class InProgressPage extends HookConsumerWidget {
         ],
       ),
       child: StausCardItem(
-          key: UniqueKey(),
-          cardHeight: 175.0,
-          serviceId: item['id'],
-          serviceTypeCode: serviceTypeCode,
-          serviceStatusCode: serviceStatusCode,
-          itemObj: item.cast<String, dynamic>(),
-          onClickCard: (dynamic value) async {
-            // Log.d("点击了喜欢按钮  --id:${item['id']}- $collectionValue");
-            // int id = item['id'];
-            // return await vm.handlerClickCollection(id, collectionValue);
-          },
+        key: UniqueKey(),
+        cardHeight: 175.0,
+        item: item,
+        onClickCard: (dynamic value) async {
+          // Log.d("点击了喜欢按钮  --id:${item['id']}- $collectionValue");
+          // int id = item['id'];
+          // return await vm.handlerClickCollection(id, collectionValue);
+        },
       ),
     );
   }
-}
+}

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

@@ -1,3 +1,4 @@
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class InProgressState {
@@ -7,7 +8,7 @@ class InProgressState {
 
   String? keyword;
   bool? isLiked;
-  List<Map<String, dynamic>> list;
+  List<GarageSaleHistoryList> list;
 
 
   InProgressState({
@@ -25,7 +26,7 @@ class InProgressState {
     bool? isLiked,
     Map<String, dynamic>? activeSortMap,
     List<Map<String, dynamic>>? activeCateGoryList,
-    List<Map<String, dynamic>>? list,
+    List<GarageSaleHistoryList>? list,
   }) {
     return InProgressState(
       loadingState: loadingState ?? this.loadingState,

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

@@ -1,9 +1,10 @@
-
 import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/newsfeed_detail_entity.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -18,10 +19,10 @@ import 'in_progress_state.dart';
 part 'in_progress_vm.g.dart';
 
 @riverpod
-class InProgressVm extends _$InProgressVm {
+class InProgressVm extends _$InProgressVm with DioCancelableMixin {
   late ServicesRespository servicesRespositoryInstance;
   bool _needShowPlaceholder = false; //是否展示LoadingView
-  int _page = 1;  // 当前页
+  int _page = 1; // 当前页
   int _limit = 10; // 每页数量
   int _count = 0; // 总条数
 
@@ -33,8 +34,8 @@ class InProgressVm extends _$InProgressVm {
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   InProgressState initState() {
@@ -44,22 +45,19 @@ class InProgressVm extends _$InProgressVm {
   }
 
   @override
-  InProgressState build(){
+  InProgressState build() {
+    servicesRespositoryInstance = ref.read(servicesRespositoryProvider);
     // 引入数据仓库
     // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider);
     final state = initState();
     Log.d("--------------------------build---------------------");
-
+    registerCancellation();
     return state;
   }
 
-
   //刷新页面状态
   void changeLoadingState(LoadState loadState, String? errorMsg) {
-    state = state.copyWith(
-        loadingState: loadState,
-        errorMessage: errorMsg
-    );
+    state = state.copyWith(loadingState: loadState, errorMessage: errorMsg);
   }
 
   // 初始化页面数据
@@ -75,7 +73,6 @@ class InProgressVm extends _$InProgressVm {
     getListData();
   }
 
-
   // 下拉刷新
   Future onRefresh() async {
     // 当前pageView 页面正处于显示状态
@@ -85,7 +82,6 @@ class InProgressVm extends _$InProgressVm {
     getListData();
   }
 
-
   // 手动进行刷新
   Future triggerRefresh() async {
     Log.d("trggerRefresh");
@@ -94,7 +90,7 @@ class InProgressVm extends _$InProgressVm {
 
   // 手动进行刷新
   Future directRefresh() async {
-    state = state.copyWith(list:[]);
+    state = state.copyWith(list: []);
     // 注意:由于 nestedscrollview 嵌套easyfresh 组件  refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口
     // https://github.com/xuelongqy/flutter_easy_refresh/issues/692
     refreshController.callRefresh();
@@ -104,7 +100,6 @@ class InProgressVm extends _$InProgressVm {
     getListData();
   }
 
-
   // 重试请求
   Future retryRequest() async {
     _page = 1;
@@ -112,195 +107,74 @@ class InProgressVm extends _$InProgressVm {
     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);
+    // 获取列表
+    var listResult = await servicesRespositoryInstance.fetchPaidServiceOrderList(
+      type: "in_progress",
+      curPage: _page,
+      cancelToken: cancelToken,
+    );
 
-    // 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");
-    // }
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
+    } else {
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
+    }
 
     // 最后赋值
     _needShowPlaceholder = false;
-
   }
 
-  handlerResultData(bool isList, {List<Map<String, dynamic>>? list, dynamic? data}){
-    Future.delayed(const Duration(seconds: 1)).then((value) {
-      if(isList){
-        // list 数据模式
-        if(list != null && list.isNotEmpty){
-          if(_page == 1){
-            state.list.clear();
-            state.list!.addAll(list);
-            refreshController.finishRefresh();
-            changeLoadingState(LoadState.State_Success, null);
-          }else {
-            final allList = state.list;
-            allList!.addAll(list);
-            state = state.copyWith(list: allList);
-            refreshController.finishLoad();
-          }
-        }else {
-          if(_page == 1){
-            state.list.clear();
-            changeLoadingState(LoadState.State_Empty, null);
-            refreshController.finishRefresh();
-          }else {
-            refreshController.finishLoad(IndicatorResult.noMore);
-          }
-        }
-      }else {
-        // 单个数据模式
-        if(data!=null){
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Success, null);
-        }else {
-          if(_page == 1){
-            refreshController.finishRefresh();
-          }else{
-            refreshController.finishLoad();
-          }
-          changeLoadingState(LoadState.State_Empty, null);
-        }
-      }
-    });
-  }
-
-  void handlerResultList(List<GarageSaleRentList>? list, bool isLoadMore) {
+  // 处理数据与展示的逻辑
+  void handleList(List<GarageSaleHistoryList>? list) {
     if (list != null && list.isNotEmpty) {
       //有数据,判断是刷新还是加载更多的数据
       if (_page == 1) {
         //刷新的方式
-        state.list!.clear();
-        state.list!.addAll(list.map((item) => item.toJson()).toList());
+        state = state.copyWith(list: list);
         refreshController.finishRefresh();
+
         //更新展示的状态
         changeLoadingState(LoadState.State_Success, null);
       } else {
         //加载更多
-        final allList = state.list;
-        allList!.addAll(list.map((item) => item.toJson()).toList());
-        state = state.copyWith(list: allList);
+        state.list.addAll(List<GarageSaleHistoryList>.from(state.list)..addAll(list));
         refreshController.finishLoad();
       }
     } else {
       if (_page == 1) {
         //展示无数据的布局
-        state.list!.clear();
+        state = state.copyWith(list: []);
         changeLoadingState(LoadState.State_Empty, null);
         refreshController.finishRefresh();
       } else {
         //展示加载完成,没有更多数据了
-        if (_page == 1) {
-          //展示无数据的布局
-          state.list!.clear();
-          changeLoadingState(LoadState.State_Empty, null);
-          refreshController.finishRefresh();
-        } else {
-          //展示加载完成,没有更多数据了
-          if(state.list!.length == 0){
-            changeLoadingState(LoadState.State_Empty, null);
-            refreshController.finishLoad();
-          }else {
-            if(_needShowPlaceholder){
-              changeLoadingState(LoadState.State_Success, null);
-            }
-          }
-          //更新展示的状态
-          refreshController.finishLoad(IndicatorResult.noMore);
-        }
+        refreshController.finishLoad(IndicatorResult.noMore);
       }
     }
   }
 
   // 设置当前的 _queryParams
-  setCurrentQueryParams(Map<String, dynamic> params){
+  setCurrentQueryParams(Map<String, dynamic> params) {
     _queryParams.addAll(params);
   }
 
   // 获取当前的 _queryParams
-  Map<String, dynamic> getCurrentQueryParams(String? key){
-    if(key!=null && key!.isNotEmpty){
+  Map<String, dynamic> getCurrentQueryParams(String? key) {
+    if (key != null && key!.isNotEmpty) {
       return _queryParams[key];
     }
     return _queryParams;
   }
 
   //  去详情页面
-  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode){
+  gotoCleanOrderDetailPage(BuildContext context, int id, int serviceTypeCode, int serviesStatusCode) {
     CleanOrderDetailPage.startInstance(id: id, serviceTypeCode: serviceTypeCode, serviesStatusCode: serviesStatusCode);
   }
-}
+}

+ 151 - 167
packages/cpt_services/lib/respository/services_respository.dart

@@ -1,10 +1,12 @@
 import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
 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/server_time.dart';
+import 'package:domain/entity/service_order_detail_entity.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/platform_export.dart';
 import 'package:plugin_platform/http/dio_engine.dart';
@@ -16,7 +18,6 @@ import 'package:shared/utils/util.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:plugin_basic/provider/http_provider/http_provider.dart';
 
-
 part 'services_respository.g.dart';
 
 @Riverpod(keepAlive: true)
@@ -35,9 +36,9 @@ class ServicesRespository {
 
   //服务 获取 分类 字典
   Future<HttpResult<Object>> fetchServiceCateGoryList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -50,8 +51,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -62,8 +65,8 @@ class ServicesRespository {
       // var data = NewsfeedForyouEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
@@ -72,9 +75,9 @@ class ServicesRespository {
 
   // 付费服务 获取 列表
   Future<HttpResult<Object>> fetchPaidServiceDataList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -87,8 +90,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -99,20 +104,19 @@ class ServicesRespository {
       var data = GarageSaleRentEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 付费/维修 服务 列表 点赞/取消点赞
   Future<HttpResult<Object>> fetchServiceLiked(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -125,8 +129,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.POST,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
     //根据返回的结果,封装原始数据为Bean/Entity对象
@@ -136,20 +142,19 @@ class ServicesRespository {
       // var data = NewsfeedForyouEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 提交评价
   Future<HttpResult<Object>> fetchPublishEvaluation(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -174,8 +179,10 @@ class ServicesRespository {
       paths: files,
       headers: headers,
       method: HttpMethod.POST,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
     //根据返回的结果,封装原始数据为Bean/Entity对象
@@ -185,20 +192,19 @@ class ServicesRespository {
       // var data = NewsfeedForyouEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 评价列表
   Future<HttpResult<Object>> fetchEvaluationDataList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -211,8 +217,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -223,8 +231,8 @@ class ServicesRespository {
       var data = GarageSaleRentEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
@@ -233,9 +241,9 @@ class ServicesRespository {
 
   // 获取 付费服务 详情信息
   Future<HttpResult<Object>> fetchPaidServiceCleanDetailInfo(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -248,8 +256,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -260,8 +270,8 @@ class ServicesRespository {
       // var data = GarageSaleRentDetailEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
@@ -270,9 +280,9 @@ class ServicesRespository {
 
   // 付费服务 下单
   Future<HttpResult<Object>> fetchPaidServiceBook(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -285,8 +295,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.POST,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
     //根据返回的结果,封装原始数据为Bean/Entity对象
@@ -296,96 +308,76 @@ class ServicesRespository {
       // var data = NewsfeedForyouEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 付费服务  订单列表
-  Future<HttpResult<Object>> fetchPaidServiceOrderList(
-      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";
+  Future<HttpResult<GarageSaleHistoryEntity>> fetchPaidServiceOrderList({
+    required String type,
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['type'] = type;
+    params['page'] = curPage.toString();
+    params['limit'] = "10";
 
     final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
-      '/api/v1/user/service/paid-service-order/index', // api 地址
+      '/api/v1/user/service/paid-service-order/index',
       params: params,
-      headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
-    //根据返回的结果,封装原始数据为Bean/Entity对象
     if (result.isSuccess) {
-      //重新赋值data或list
       final json = result.getDataJson();
-      var data = GarageSaleRentEntity.fromJson(json!);
-      //重新赋值data或list
-      return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
-        ToastEngine.show("${result.errorMsg}");
-      }
+      var data = GarageSaleHistoryEntity.fromJson(json!);
+      return result.convert<GarageSaleHistoryEntity>(data: data);
     }
     return result.convert();
   }
 
-
   // 获取 付费服务 订单详情
-  Future<HttpResult<Object>> fetchPaidServiceCleanOrderDetailInfo(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+  Future<HttpResult<ServiceOrderDetailEntity>> fetchPaidServiceCleanOrderDetail({
+    required String id,
+    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";
+    params['id'] = id;
 
     final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
-      '/api/v1/user/service/paid-service-order/detail', // api 地址
+      '/api/v1/user/service/paid-service-order/detail',
       params: params,
-      headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
-    //根据返回的结果,封装原始数据为Bean/Entity对象
     if (result.isSuccess) {
-      //重新赋值data或list
       final json = result.getDataJson();
-      // var data = GarageSaleRentDetailEntity.fromJson(json!);
-      //重新赋值data或list
-      return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
-        ToastEngine.show("${result.errorMsg}");
-      }
+      var data = ServiceOrderDetailEntity.fromJson(json!);
+      return result.convert<ServiceOrderDetailEntity>(data: data);
     }
     return result.convert();
   }
 
-
   // 获取 付费订单实际需要支付的价格
   Future<HttpResult<Object>> fetchPaidServiceCleanOrderPrice(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -398,8 +390,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -410,60 +404,46 @@ class ServicesRespository {
       // var data = GarageSaleRentDetailEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 付费服务 取消订单
-  Future<HttpResult<Object>> fetchCancelPaidServiceOrder(
-      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";
+  Future<HttpResult> fetchCancelPaidServiceOrder({
+    required String? id,
+    required String? reason,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['id'] = id ?? "";
+    params['cancel_reason'] = reason ?? "";
 
     final result = await dioEngine.requestNetResult(
-      // ApiConstants.apiServerTime, // api 地址
-      '/api/v1/user/service/paid-service-order/cancel', // api 地址
+      '/api/v1/user/service/paid-service-order/cancel',
       params: params,
-      headers: headers,
       method: HttpMethod.POST,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      networkDebounce: true,
       cancelToken: cancelToken,
     );
-    //根据返回的结果,封装原始数据为Bean/Entity对象
+
     if (result.isSuccess) {
-      //重新赋值data或list
-      final json = result.getDataJson();
-      // var data = NewsfeedForyouEntity.fromJson(json!);
-      //重新赋值data或list
-      return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
-        ToastEngine.show("${result.errorMsg}");
-      }
+      return result.convert();
     }
     return result.convert();
   }
 
-
   ///-------------------咨询类---------------------------------
 
-
   // 维修服务  列表
   Future<HttpResult<Object>> fetchRepairServiceList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -476,8 +456,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -488,8 +470,8 @@ class ServicesRespository {
       var data = GarageSaleRentEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
@@ -498,9 +480,9 @@ class ServicesRespository {
 
   // 获取 repair 详情信息
   Future<HttpResult<Object>> fetchServiceRepairDetailInfo(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -513,8 +495,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -525,20 +509,19 @@ class ServicesRespository {
       var data = GarageSaleRentDetailEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 维修服务 提交咨询
   Future<HttpResult<Object>> fetchRepairServiceSubmit(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -551,8 +534,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.POST,
-      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: true,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
     //根据返回的结果,封装原始数据为Bean/Entity对象
@@ -562,20 +547,19 @@ class ServicesRespository {
       // var data = NewsfeedForyouEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: json);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
 
-
   // 维修服务  订单列表
   Future<HttpResult<Object>> fetchRepairServiceOrderList(
-      Map<String, dynamic>? data, {
-        CancelToken? cancelToken,
-      }) async {
+    Map<String, dynamic>? data, {
+    CancelToken? cancelToken,
+  }) async {
     Map<String, dynamic> params = {};
     params = data!;
     Map<String, String> headers = {};
@@ -588,8 +572,10 @@ class ServicesRespository {
       params: params,
       headers: headers,
       method: HttpMethod.GET,
-      isShowLoadingDialog: false,  //是否展示默认的Loading弹窗
-      networkDebounce: true,   //是否防抖防止重复请求
+      isShowLoadingDialog: false,
+      //是否展示默认的Loading弹窗
+      networkDebounce: true,
+      //是否防抖防止重复请求
       cancelToken: cancelToken,
     );
 
@@ -600,13 +586,11 @@ class ServicesRespository {
       var data = GarageSaleRentEntity.fromJson(json!);
       //重新赋值data或list
       return result.convert(data: data);
-    }else {
-      if(result.errorMsg != null && result.errorMsg!.isNotEmpty){
+    } else {
+      if (result.errorMsg != null && result.errorMsg!.isNotEmpty) {
         ToastEngine.show("${result.errorMsg}");
       }
     }
     return result.convert();
   }
-
-
 }

+ 75 - 0
packages/cs_domain/lib/entity/garage_sale_history_entity.dart

@@ -0,0 +1,75 @@
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/garage_sale_history_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/garage_sale_history_entity.g.dart';
+
+@JsonSerializable()
+class GarageSaleHistoryEntity {
+	int count = 0;
+	int page = 0;
+	int limit = 0;
+	@JSONField(name: "count_page")
+	int countPage = 0;
+	List<GarageSaleHistoryList> list = [];
+
+	GarageSaleHistoryEntity();
+
+	factory GarageSaleHistoryEntity.fromJson(Map<String, dynamic> json) => $GarageSaleHistoryEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $GarageSaleHistoryEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class GarageSaleHistoryList {
+	String? id;
+	String? sn;
+	@JSONField(name: "order_status")
+	String? orderStatus;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	IdNameEntity? service;
+	IdNameEntity? merchant;
+	@JSONField(name: "order_products")
+	List<GarageSaleHistoryListOrderProducts> orderProducts = [];
+
+	GarageSaleHistoryList();
+
+	factory GarageSaleHistoryList.fromJson(Map<String, dynamic> json) => $GarageSaleHistoryListFromJson(json);
+
+	Map<String, dynamic> toJson() => $GarageSaleHistoryListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+
+@JsonSerializable()
+class GarageSaleHistoryListOrderProducts {
+	String? id;
+	@JSONField(name: "product_name")
+	String? productName;
+	int quantity = 0;
+	@JSONField(name: "total_amount")
+	String? totalAmount;
+	@JSONField(name: "planned_service_at")
+	String? plannedServiceAt;
+
+	GarageSaleHistoryListOrderProducts();
+
+	factory GarageSaleHistoryListOrderProducts.fromJson(Map<String, dynamic> json) => $GarageSaleHistoryListOrderProductsFromJson(json);
+
+	Map<String, dynamic> toJson() => $GarageSaleHistoryListOrderProductsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 47 - 47
packages/cs_domain/lib/entity/garage_sale_rent_detail_entity.dart

@@ -1,48 +1,48 @@
-import 'package:domain/generated/json/base/json_field.dart';
-import 'package:domain/generated/json/garage_sale_rent_detail_entity.g.dart';
-import 'dart:convert';
-export 'package:domain/generated/json/garage_sale_rent_detail_entity.g.dart';
-
-@JsonSerializable()
-class GarageSaleRentDetailEntity {
-	int? id;
-	String? title;
-	int? price;
-	String? description;
-	List<String>? resources;
-	@JSONField(name: "created_at")
-	String? createdAt;
-	@JSONField(name: "likes_count")
-	int? likesCount;
-	String? contact;
-	GarageSaleRentDetailAccount? account;
-
-	GarageSaleRentDetailEntity();
-
-	factory GarageSaleRentDetailEntity.fromJson(Map<String, dynamic> json) => $GarageSaleRentDetailEntityFromJson(json);
-
-	Map<String, dynamic> toJson() => $GarageSaleRentDetailEntityToJson(this);
-
-	@override
-	String toString() {
-		return jsonEncode(this);
-	}
-}
-
-@JsonSerializable()
-class GarageSaleRentDetailAccount {
-	int? id;
-	String? name;
-	String? avatar;
-
-	GarageSaleRentDetailAccount();
-
-	factory GarageSaleRentDetailAccount.fromJson(Map<String, dynamic> json) => $GarageSaleRentDetailAccountFromJson(json);
-
-	Map<String, dynamic> toJson() => $GarageSaleRentDetailAccountToJson(this);
-
-	@override
-	String toString() {
-		return jsonEncode(this);
-	}
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/garage_sale_rent_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/garage_sale_rent_detail_entity.g.dart';
+
+@JsonSerializable()
+class GarageSaleRentDetailEntity {
+	int? id;
+	String? title;
+	int? price;
+	String? description;
+	List<String>? resources;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	@JSONField(name: "likes_count")
+	int? likesCount;
+	String? contact;
+	GarageSaleRentDetailAccount? account;
+
+	GarageSaleRentDetailEntity();
+
+	factory GarageSaleRentDetailEntity.fromJson(Map<String, dynamic> json) => $GarageSaleRentDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $GarageSaleRentDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class GarageSaleRentDetailAccount {
+	int? id;
+	String? name;
+	String? avatar;
+
+	GarageSaleRentDetailAccount();
+
+	factory GarageSaleRentDetailAccount.fromJson(Map<String, dynamic> json) => $GarageSaleRentDetailAccountFromJson(json);
+
+	Map<String, dynamic> toJson() => $GarageSaleRentDetailAccountToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
 }

+ 141 - 0
packages/cs_domain/lib/entity/service_order_detail_entity.dart

@@ -0,0 +1,141 @@
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/service_order_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/service_order_detail_entity.g.dart';
+
+@JsonSerializable()
+class ServiceOrderDetailEntity {
+	String? id;
+	String? sn;
+	@JSONField(name: "total_amount")
+	String? totalAmount;
+	@JSONField(name: "paid_at")
+	String? paidAt;
+	String? notes;
+	ServiceOrderDetailAccount? account;
+	@JSONField(name: "order_service")
+	ServiceOrderDetailOrderService? orderService;
+	IdNameEntity? merchant;
+	@JSONField(name: "order_products")
+	List<ServiceOrderDetailOrderProducts>? orderProducts = [];
+	ServiceOrderDetailEstate? estate;
+	@JSONField(name: "estate_unit")
+	ServiceOrderDetailEstateUnit? estateUnit;
+
+	ServiceOrderDetailEntity();
+
+	factory ServiceOrderDetailEntity.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class ServiceOrderDetailAccount {
+	String? id;
+	String? name;
+	String? avatar;
+	String? phone;
+
+	ServiceOrderDetailAccount();
+
+	factory ServiceOrderDetailAccount.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailAccountFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailAccountToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class ServiceOrderDetailOrderService {
+	String? id;
+	String? name;
+	@JSONField(name: "evaluations_avg_score")
+	double evaluationsAvgScore = 0.0;
+
+	ServiceOrderDetailOrderService();
+
+	factory ServiceOrderDetailOrderService.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailOrderServiceFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailOrderServiceToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+
+@JsonSerializable()
+class ServiceOrderDetailOrderProducts {
+	String? id;
+	@JSONField(name: "product_name")
+	String? productName;
+	@JSONField(name: "product_amount")
+	String? productAmount;
+	@JSONField(name: "urgent_amount")
+	String? urgentAmount;
+	@JSONField(name: "holiday_amount")
+	String? holidayAmount;
+	@JSONField(name: "night_amount")
+	String? nightAmount;
+	int quantity = 0;
+	@JSONField(name: "total_amount")
+	String? totalAmount;
+	@JSONField(name: "planned_service_at")
+	String? plannedServiceAt;
+
+	ServiceOrderDetailOrderProducts();
+
+	factory ServiceOrderDetailOrderProducts.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailOrderProductsFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailOrderProductsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class ServiceOrderDetailEstate {
+	String? id;
+	String? name;
+
+	ServiceOrderDetailEstate();
+
+	factory ServiceOrderDetailEstate.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailEstateFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailEstateToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class ServiceOrderDetailEstateUnit {
+	String? id;
+	String? unit;
+	String? address;
+
+	ServiceOrderDetailEstateUnit();
+
+	factory ServiceOrderDetailEstateUnit.fromJson(Map<String, dynamic> json) => $ServiceOrderDetailEstateUnitFromJson(json);
+
+	Map<String, dynamic> toJson() => $ServiceOrderDetailEstateUnitToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 38 - 0
packages/cs_domain/lib/generated/json/base/json_convert_content.dart

@@ -17,6 +17,7 @@ import 'package:domain/entity/form_list_entity.dart';
 import 'package:domain/entity/form_option_entity.dart';
 import 'package:domain/entity/form_submitted_entity.dart';
 import 'package:domain/entity/form_submitted_page_entity.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
 import 'package:domain/entity/garage_sale_rent_detail_entity.dart';
 import 'package:domain/entity/garage_sale_rent_entity.dart';
 import 'package:domain/entity/home_list_entity.dart';
@@ -55,6 +56,7 @@ import 'package:domain/entity/rewards_my_detail_entity.dart';
 import 'package:domain/entity/rewards_my_entity.dart';
 import 'package:domain/entity/rewards_search_entity.dart';
 import 'package:domain/entity/server_time.dart';
+import 'package:domain/entity/service_order_detail_entity.dart';
 import 'package:domain/entity/text_kon_entity.dart';
 import 'package:domain/entity/user_me_entity.dart';
 import 'package:domain/entity/visitor_page_entity.dart';
@@ -265,6 +267,15 @@ class JsonConvert {
     if (<FormSubmittedPageEntity>[] is M) {
       return data.map<FormSubmittedPageEntity>((Map<String, dynamic> e) => FormSubmittedPageEntity.fromJson(e)).toList() as M;
     }
+    if (<GarageSaleHistoryEntity>[] is M) {
+      return data.map<GarageSaleHistoryEntity>((Map<String, dynamic> e) => GarageSaleHistoryEntity.fromJson(e)).toList() as M;
+    }
+    if (<GarageSaleHistoryList>[] is M) {
+      return data.map<GarageSaleHistoryList>((Map<String, dynamic> e) => GarageSaleHistoryList.fromJson(e)).toList() as M;
+    }
+    if (<GarageSaleHistoryListOrderProducts>[] is M) {
+      return data.map<GarageSaleHistoryListOrderProducts>((Map<String, dynamic> e) => GarageSaleHistoryListOrderProducts.fromJson(e)).toList() as M;
+    }
     if (<GarageSaleRentDetailEntity>[] is M) {
       return data.map<GarageSaleRentDetailEntity>((Map<String, dynamic> e) => GarageSaleRentDetailEntity.fromJson(e)).toList() as M;
     }
@@ -511,6 +522,24 @@ class JsonConvert {
     if (<ServerTime>[] is M) {
       return data.map<ServerTime>((Map<String, dynamic> e) => ServerTime.fromJson(e)).toList() as M;
     }
+    if (<ServiceOrderDetailEntity>[] is M) {
+      return data.map<ServiceOrderDetailEntity>((Map<String, dynamic> e) => ServiceOrderDetailEntity.fromJson(e)).toList() as M;
+    }
+    if (<ServiceOrderDetailAccount>[] is M) {
+      return data.map<ServiceOrderDetailAccount>((Map<String, dynamic> e) => ServiceOrderDetailAccount.fromJson(e)).toList() as M;
+    }
+    if (<ServiceOrderDetailOrderService>[] is M) {
+      return data.map<ServiceOrderDetailOrderService>((Map<String, dynamic> e) => ServiceOrderDetailOrderService.fromJson(e)).toList() as M;
+    }
+    if (<ServiceOrderDetailOrderProducts>[] is M) {
+      return data.map<ServiceOrderDetailOrderProducts>((Map<String, dynamic> e) => ServiceOrderDetailOrderProducts.fromJson(e)).toList() as M;
+    }
+    if (<ServiceOrderDetailEstate>[] is M) {
+      return data.map<ServiceOrderDetailEstate>((Map<String, dynamic> e) => ServiceOrderDetailEstate.fromJson(e)).toList() as M;
+    }
+    if (<ServiceOrderDetailEstateUnit>[] is M) {
+      return data.map<ServiceOrderDetailEstateUnit>((Map<String, dynamic> e) => ServiceOrderDetailEstateUnit.fromJson(e)).toList() as M;
+    }
     if (<TextKonEntity>[] is M) {
       return data.map<TextKonEntity>((Map<String, dynamic> e) => TextKonEntity.fromJson(e)).toList() as M;
     }
@@ -586,6 +615,9 @@ class JsonConvertClassCollection {
     (FormSubmittedEntity).toString(): FormSubmittedEntity.fromJson,
     (FormSubmittedEstateOnlineForm).toString(): FormSubmittedEstateOnlineForm.fromJson,
     (FormSubmittedPageEntity).toString(): FormSubmittedPageEntity.fromJson,
+    (GarageSaleHistoryEntity).toString(): GarageSaleHistoryEntity.fromJson,
+    (GarageSaleHistoryList).toString(): GarageSaleHistoryList.fromJson,
+    (GarageSaleHistoryListOrderProducts).toString(): GarageSaleHistoryListOrderProducts.fromJson,
     (GarageSaleRentDetailEntity).toString(): GarageSaleRentDetailEntity.fromJson,
     (GarageSaleRentDetailAccount).toString(): GarageSaleRentDetailAccount.fromJson,
     (GarageSaleRentEntity).toString(): GarageSaleRentEntity.fromJson,
@@ -668,6 +700,12 @@ class JsonConvertClassCollection {
     (RewardsSearchEntity).toString(): RewardsSearchEntity.fromJson,
     (RewardsSearchRewards).toString(): RewardsSearchRewards.fromJson,
     (ServerTime).toString(): ServerTime.fromJson,
+    (ServiceOrderDetailEntity).toString(): ServiceOrderDetailEntity.fromJson,
+    (ServiceOrderDetailAccount).toString(): ServiceOrderDetailAccount.fromJson,
+    (ServiceOrderDetailOrderService).toString(): ServiceOrderDetailOrderService.fromJson,
+    (ServiceOrderDetailOrderProducts).toString(): ServiceOrderDetailOrderProducts.fromJson,
+    (ServiceOrderDetailEstate).toString(): ServiceOrderDetailEstate.fromJson,
+    (ServiceOrderDetailEstateUnit).toString(): ServiceOrderDetailEstateUnit.fromJson,
     (TextKonEntity).toString(): TextKonEntity.fromJson,
     (UserMeEntity).toString(): UserMeEntity.fromJson,
     (UserMeHouseholds).toString(): UserMeHouseholds.fromJson,

+ 176 - 0
packages/cs_domain/lib/generated/json/garage_sale_history_entity.g.dart

@@ -0,0 +1,176 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/garage_sale_history_entity.dart';
+import 'package:domain/entity/id_name_entity.dart';
+
+
+GarageSaleHistoryEntity $GarageSaleHistoryEntityFromJson(Map<String, dynamic> json) {
+  final GarageSaleHistoryEntity garageSaleHistoryEntity = GarageSaleHistoryEntity();
+  final int? count = jsonConvert.convert<int>(json['count']);
+  if (count != null) {
+    garageSaleHistoryEntity.count = count;
+  }
+  final int? page = jsonConvert.convert<int>(json['page']);
+  if (page != null) {
+    garageSaleHistoryEntity.page = page;
+  }
+  final int? limit = jsonConvert.convert<int>(json['limit']);
+  if (limit != null) {
+    garageSaleHistoryEntity.limit = limit;
+  }
+  final int? countPage = jsonConvert.convert<int>(json['count_page']);
+  if (countPage != null) {
+    garageSaleHistoryEntity.countPage = countPage;
+  }
+  final List<GarageSaleHistoryList>? list = (json['list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<GarageSaleHistoryList>(e) as GarageSaleHistoryList).toList();
+  if (list != null) {
+    garageSaleHistoryEntity.list = list;
+  }
+  return garageSaleHistoryEntity;
+}
+
+Map<String, dynamic> $GarageSaleHistoryEntityToJson(GarageSaleHistoryEntity 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 GarageSaleHistoryEntityExtension on GarageSaleHistoryEntity {
+  GarageSaleHistoryEntity copyWith({
+    int? count,
+    int? page,
+    int? limit,
+    int? countPage,
+    List<GarageSaleHistoryList>? list,
+  }) {
+    return GarageSaleHistoryEntity()
+      ..count = count ?? this.count
+      ..page = page ?? this.page
+      ..limit = limit ?? this.limit
+      ..countPage = countPage ?? this.countPage
+      ..list = list ?? this.list;
+  }
+}
+
+GarageSaleHistoryList $GarageSaleHistoryListFromJson(Map<String, dynamic> json) {
+  final GarageSaleHistoryList garageSaleHistoryList = GarageSaleHistoryList();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    garageSaleHistoryList.id = id;
+  }
+  final String? sn = jsonConvert.convert<String>(json['sn']);
+  if (sn != null) {
+    garageSaleHistoryList.sn = sn;
+  }
+  final String? orderStatus = jsonConvert.convert<String>(json['order_status']);
+  if (orderStatus != null) {
+    garageSaleHistoryList.orderStatus = orderStatus;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    garageSaleHistoryList.createdAt = createdAt;
+  }
+  final IdNameEntity? service = jsonConvert.convert<IdNameEntity>(json['service']);
+  if (service != null) {
+    garageSaleHistoryList.service = service;
+  }
+  final IdNameEntity? merchant = jsonConvert.convert<IdNameEntity>(json['merchant']);
+  if (merchant != null) {
+    garageSaleHistoryList.merchant = merchant;
+  }
+  final List<GarageSaleHistoryListOrderProducts>? orderProducts = (json['order_products'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<GarageSaleHistoryListOrderProducts>(e) as GarageSaleHistoryListOrderProducts).toList();
+  if (orderProducts != null) {
+    garageSaleHistoryList.orderProducts = orderProducts;
+  }
+  return garageSaleHistoryList;
+}
+
+Map<String, dynamic> $GarageSaleHistoryListToJson(GarageSaleHistoryList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['sn'] = entity.sn;
+  data['order_status'] = entity.orderStatus;
+  data['created_at'] = entity.createdAt;
+  data['service'] = entity.service?.toJson();
+  data['merchant'] = entity.merchant?.toJson();
+  data['order_products'] = entity.orderProducts.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension GarageSaleHistoryListExtension on GarageSaleHistoryList {
+  GarageSaleHistoryList copyWith({
+    String? id,
+    String? sn,
+    String? orderStatus,
+    String? createdAt,
+    IdNameEntity? service,
+    IdNameEntity? merchant,
+    List<GarageSaleHistoryListOrderProducts>? orderProducts,
+  }) {
+    return GarageSaleHistoryList()
+      ..id = id ?? this.id
+      ..sn = sn ?? this.sn
+      ..orderStatus = orderStatus ?? this.orderStatus
+      ..createdAt = createdAt ?? this.createdAt
+      ..service = service ?? this.service
+      ..merchant = merchant ?? this.merchant
+      ..orderProducts = orderProducts ?? this.orderProducts;
+  }
+}
+
+GarageSaleHistoryListOrderProducts $GarageSaleHistoryListOrderProductsFromJson(Map<String, dynamic> json) {
+  final GarageSaleHistoryListOrderProducts garageSaleHistoryListOrderProducts = GarageSaleHistoryListOrderProducts();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    garageSaleHistoryListOrderProducts.id = id;
+  }
+  final String? productName = jsonConvert.convert<String>(json['product_name']);
+  if (productName != null) {
+    garageSaleHistoryListOrderProducts.productName = productName;
+  }
+  final int? quantity = jsonConvert.convert<int>(json['quantity']);
+  if (quantity != null) {
+    garageSaleHistoryListOrderProducts.quantity = quantity;
+  }
+  final String? totalAmount = jsonConvert.convert<String>(json['total_amount']);
+  if (totalAmount != null) {
+    garageSaleHistoryListOrderProducts.totalAmount = totalAmount;
+  }
+  final String? plannedServiceAt = jsonConvert.convert<String>(json['planned_service_at']);
+  if (plannedServiceAt != null) {
+    garageSaleHistoryListOrderProducts.plannedServiceAt = plannedServiceAt;
+  }
+  return garageSaleHistoryListOrderProducts;
+}
+
+Map<String, dynamic> $GarageSaleHistoryListOrderProductsToJson(GarageSaleHistoryListOrderProducts 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 GarageSaleHistoryListOrderProductsExtension on GarageSaleHistoryListOrderProducts {
+  GarageSaleHistoryListOrderProducts copyWith({
+    String? id,
+    String? productName,
+    int? quantity,
+    String? totalAmount,
+    String? plannedServiceAt,
+  }) {
+    return GarageSaleHistoryListOrderProducts()
+      ..id = id ?? this.id
+      ..productName = productName ?? this.productName
+      ..quantity = quantity ?? this.quantity
+      ..totalAmount = totalAmount ?? this.totalAmount
+      ..plannedServiceAt = plannedServiceAt ?? this.plannedServiceAt;
+  }
+}

+ 331 - 0
packages/cs_domain/lib/generated/json/service_order_detail_entity.g.dart

@@ -0,0 +1,331 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/service_order_detail_entity.dart';
+import 'package:domain/entity/id_name_entity.dart';
+
+
+ServiceOrderDetailEntity $ServiceOrderDetailEntityFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailEntity serviceOrderDetailEntity = ServiceOrderDetailEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailEntity.id = id;
+  }
+  final String? sn = jsonConvert.convert<String>(json['sn']);
+  if (sn != null) {
+    serviceOrderDetailEntity.sn = sn;
+  }
+  final String? totalAmount = jsonConvert.convert<String>(json['total_amount']);
+  if (totalAmount != null) {
+    serviceOrderDetailEntity.totalAmount = totalAmount;
+  }
+  final String? paidAt = jsonConvert.convert<String>(json['paid_at']);
+  if (paidAt != null) {
+    serviceOrderDetailEntity.paidAt = paidAt;
+  }
+  final String? notes = jsonConvert.convert<String>(json['notes']);
+  if (notes != null) {
+    serviceOrderDetailEntity.notes = notes;
+  }
+  final ServiceOrderDetailAccount? account = jsonConvert.convert<ServiceOrderDetailAccount>(json['account']);
+  if (account != null) {
+    serviceOrderDetailEntity.account = account;
+  }
+  final ServiceOrderDetailOrderService? orderService = jsonConvert.convert<ServiceOrderDetailOrderService>(json['order_service']);
+  if (orderService != null) {
+    serviceOrderDetailEntity.orderService = orderService;
+  }
+  final IdNameEntity? merchant = jsonConvert.convert<IdNameEntity>(json['merchant']);
+  if (merchant != null) {
+    serviceOrderDetailEntity.merchant = merchant;
+  }
+  final List<ServiceOrderDetailOrderProducts>? orderProducts = (json['order_products'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<ServiceOrderDetailOrderProducts>(e) as ServiceOrderDetailOrderProducts).toList();
+  if (orderProducts != null) {
+    serviceOrderDetailEntity.orderProducts = orderProducts;
+  }
+  final ServiceOrderDetailEstate? estate = jsonConvert.convert<ServiceOrderDetailEstate>(json['estate']);
+  if (estate != null) {
+    serviceOrderDetailEntity.estate = estate;
+  }
+  final ServiceOrderDetailEstateUnit? estateUnit = jsonConvert.convert<ServiceOrderDetailEstateUnit>(json['estate_unit']);
+  if (estateUnit != null) {
+    serviceOrderDetailEntity.estateUnit = estateUnit;
+  }
+  return serviceOrderDetailEntity;
+}
+
+Map<String, dynamic> $ServiceOrderDetailEntityToJson(ServiceOrderDetailEntity 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['order_products'] = entity.orderProducts?.map((v) => v.toJson()).toList();
+  data['estate'] = entity.estate?.toJson();
+  data['estate_unit'] = entity.estateUnit?.toJson();
+  return data;
+}
+
+extension ServiceOrderDetailEntityExtension on ServiceOrderDetailEntity {
+  ServiceOrderDetailEntity copyWith({
+    String? id,
+    String? sn,
+    String? totalAmount,
+    String? paidAt,
+    String? notes,
+    ServiceOrderDetailAccount? account,
+    ServiceOrderDetailOrderService? orderService,
+    IdNameEntity? merchant,
+    List<ServiceOrderDetailOrderProducts>? orderProducts,
+    ServiceOrderDetailEstate? estate,
+    ServiceOrderDetailEstateUnit? estateUnit,
+  }) {
+    return ServiceOrderDetailEntity()
+      ..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
+      ..orderProducts = orderProducts ?? this.orderProducts
+      ..estate = estate ?? this.estate
+      ..estateUnit = estateUnit ?? this.estateUnit;
+  }
+}
+
+ServiceOrderDetailAccount $ServiceOrderDetailAccountFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailAccount serviceOrderDetailAccount = ServiceOrderDetailAccount();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailAccount.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    serviceOrderDetailAccount.name = name;
+  }
+  final String? avatar = jsonConvert.convert<String>(json['avatar']);
+  if (avatar != null) {
+    serviceOrderDetailAccount.avatar = avatar;
+  }
+  final String? phone = jsonConvert.convert<String>(json['phone']);
+  if (phone != null) {
+    serviceOrderDetailAccount.phone = phone;
+  }
+  return serviceOrderDetailAccount;
+}
+
+Map<String, dynamic> $ServiceOrderDetailAccountToJson(ServiceOrderDetailAccount 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 ServiceOrderDetailAccountExtension on ServiceOrderDetailAccount {
+  ServiceOrderDetailAccount copyWith({
+    String? id,
+    String? name,
+    String? avatar,
+    String? phone,
+  }) {
+    return ServiceOrderDetailAccount()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..avatar = avatar ?? this.avatar
+      ..phone = phone ?? this.phone;
+  }
+}
+
+ServiceOrderDetailOrderService $ServiceOrderDetailOrderServiceFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailOrderService serviceOrderDetailOrderService = ServiceOrderDetailOrderService();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailOrderService.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    serviceOrderDetailOrderService.name = name;
+  }
+  final double? evaluationsAvgScore = jsonConvert.convert<double>(json['evaluations_avg_score']);
+  if (evaluationsAvgScore != null) {
+    serviceOrderDetailOrderService.evaluationsAvgScore = evaluationsAvgScore;
+  }
+  return serviceOrderDetailOrderService;
+}
+
+Map<String, dynamic> $ServiceOrderDetailOrderServiceToJson(ServiceOrderDetailOrderService 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 ServiceOrderDetailOrderServiceExtension on ServiceOrderDetailOrderService {
+  ServiceOrderDetailOrderService copyWith({
+    String? id,
+    String? name,
+    double? evaluationsAvgScore,
+  }) {
+    return ServiceOrderDetailOrderService()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..evaluationsAvgScore = evaluationsAvgScore ?? this.evaluationsAvgScore;
+  }
+}
+
+ServiceOrderDetailOrderProducts $ServiceOrderDetailOrderProductsFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailOrderProducts serviceOrderDetailOrderProducts = ServiceOrderDetailOrderProducts();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailOrderProducts.id = id;
+  }
+  final String? productName = jsonConvert.convert<String>(json['product_name']);
+  if (productName != null) {
+    serviceOrderDetailOrderProducts.productName = productName;
+  }
+  final String? productAmount = jsonConvert.convert<String>(json['product_amount']);
+  if (productAmount != null) {
+    serviceOrderDetailOrderProducts.productAmount = productAmount;
+  }
+  final String? urgentAmount = jsonConvert.convert<String>(json['urgent_amount']);
+  if (urgentAmount != null) {
+    serviceOrderDetailOrderProducts.urgentAmount = urgentAmount;
+  }
+  final String? holidayAmount = jsonConvert.convert<String>(json['holiday_amount']);
+  if (holidayAmount != null) {
+    serviceOrderDetailOrderProducts.holidayAmount = holidayAmount;
+  }
+  final String? nightAmount = jsonConvert.convert<String>(json['night_amount']);
+  if (nightAmount != null) {
+    serviceOrderDetailOrderProducts.nightAmount = nightAmount;
+  }
+  final int? quantity = jsonConvert.convert<int>(json['quantity']);
+  if (quantity != null) {
+    serviceOrderDetailOrderProducts.quantity = quantity;
+  }
+  final String? totalAmount = jsonConvert.convert<String>(json['total_amount']);
+  if (totalAmount != null) {
+    serviceOrderDetailOrderProducts.totalAmount = totalAmount;
+  }
+  final String? plannedServiceAt = jsonConvert.convert<String>(json['planned_service_at']);
+  if (plannedServiceAt != null) {
+    serviceOrderDetailOrderProducts.plannedServiceAt = plannedServiceAt;
+  }
+  return serviceOrderDetailOrderProducts;
+}
+
+Map<String, dynamic> $ServiceOrderDetailOrderProductsToJson(ServiceOrderDetailOrderProducts entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['product_name'] = entity.productName;
+  data['product_amount'] = entity.productAmount;
+  data['urgent_amount'] = entity.urgentAmount;
+  data['holiday_amount'] = entity.holidayAmount;
+  data['night_amount'] = entity.nightAmount;
+  data['quantity'] = entity.quantity;
+  data['total_amount'] = entity.totalAmount;
+  data['planned_service_at'] = entity.plannedServiceAt;
+  return data;
+}
+
+extension ServiceOrderDetailOrderProductsExtension on ServiceOrderDetailOrderProducts {
+  ServiceOrderDetailOrderProducts copyWith({
+    String? id,
+    String? productName,
+    String? productAmount,
+    String? urgentAmount,
+    String? holidayAmount,
+    String? nightAmount,
+    int? quantity,
+    String? totalAmount,
+    String? plannedServiceAt,
+  }) {
+    return ServiceOrderDetailOrderProducts()
+      ..id = id ?? this.id
+      ..productName = productName ?? this.productName
+      ..productAmount = productAmount ?? this.productAmount
+      ..urgentAmount = urgentAmount ?? this.urgentAmount
+      ..holidayAmount = holidayAmount ?? this.holidayAmount
+      ..nightAmount = nightAmount ?? this.nightAmount
+      ..quantity = quantity ?? this.quantity
+      ..totalAmount = totalAmount ?? this.totalAmount
+      ..plannedServiceAt = plannedServiceAt ?? this.plannedServiceAt;
+  }
+}
+
+ServiceOrderDetailEstate $ServiceOrderDetailEstateFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailEstate serviceOrderDetailEstate = ServiceOrderDetailEstate();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailEstate.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    serviceOrderDetailEstate.name = name;
+  }
+  return serviceOrderDetailEstate;
+}
+
+Map<String, dynamic> $ServiceOrderDetailEstateToJson(ServiceOrderDetailEstate entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  return data;
+}
+
+extension ServiceOrderDetailEstateExtension on ServiceOrderDetailEstate {
+  ServiceOrderDetailEstate copyWith({
+    String? id,
+    String? name,
+  }) {
+    return ServiceOrderDetailEstate()
+      ..id = id ?? this.id
+      ..name = name ?? this.name;
+  }
+}
+
+ServiceOrderDetailEstateUnit $ServiceOrderDetailEstateUnitFromJson(Map<String, dynamic> json) {
+  final ServiceOrderDetailEstateUnit serviceOrderDetailEstateUnit = ServiceOrderDetailEstateUnit();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    serviceOrderDetailEstateUnit.id = id;
+  }
+  final String? unit = jsonConvert.convert<String>(json['unit']);
+  if (unit != null) {
+    serviceOrderDetailEstateUnit.unit = unit;
+  }
+  final String? address = jsonConvert.convert<String>(json['address']);
+  if (address != null) {
+    serviceOrderDetailEstateUnit.address = address;
+  }
+  return serviceOrderDetailEstateUnit;
+}
+
+Map<String, dynamic> $ServiceOrderDetailEstateUnitToJson(ServiceOrderDetailEstateUnit entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['unit'] = entity.unit;
+  data['address'] = entity.address;
+  return data;
+}
+
+extension ServiceOrderDetailEstateUnitExtension on ServiceOrderDetailEstateUnit {
+  ServiceOrderDetailEstateUnit copyWith({
+    String? id,
+    String? unit,
+    String? address,
+  }) {
+    return ServiceOrderDetailEstateUnit()
+      ..id = id ?? this.id
+      ..unit = unit ?? this.unit
+      ..address = address ?? this.address;
+  }
+}