Browse Source

update community

glglove 4 months ago
parent
commit
3502160bff
100 changed files with 3809 additions and 1219 deletions
  1. 1 1
      app/lib/main.dart
  2. 1 1
      packages/cpt_auth/lib/modules/auth_login/auth_login_page.dart
  3. 9 9
      packages/cpt_facility/lib/modules/facility/facility_page.dart
  4. 52 0
      packages/cpt_facility/lib/modules/facility/facility_types.dart
  5. 20 12
      packages/cpt_form/lib/modules/apply/attachment_page.dart
  6. 138 93
      packages/cpt_form/lib/modules/apply/form_payment_page.dart
  7. 33 8
      packages/cpt_form/lib/modules/apply/form_terms_page.dart
  8. 68 24
      packages/cpt_form/lib/modules/apply/guest_vehicle_page.dart
  9. 24 14
      packages/cpt_form/lib/modules/apply/large_text_box_page.dart
  10. 44 13
      packages/cpt_form/lib/modules/apply/moving_company_page.dart
  11. 55 30
      packages/cpt_form/lib/modules/apply/moving_date_page.dart
  12. 23 12
      packages/cpt_form/lib/modules/apply/note_management_page.dart
  13. 44 14
      packages/cpt_form/lib/modules/apply/renovation_company_page.dart
  14. 61 33
      packages/cpt_form/lib/modules/apply/renovation_date_page.dart
  15. 75 34
      packages/cpt_form/lib/modules/apply/signature_page.dart
  16. 21 3
      packages/cpt_form/lib/modules/apply/type_of_application_page.dart
  17. 87 55
      packages/cpt_form/lib/modules/apply/vehicle_info_page.dart
  18. 31 8
      packages/cpt_form/lib/modules/apply/vm/apply_state.dart
  19. 114 11
      packages/cpt_form/lib/modules/apply/vm/apply_view_model.dart
  20. 1 1
      packages/cpt_form/lib/modules/apply/vm/apply_view_model.g.dart
  21. 38 22
      packages/cpt_form/lib/modules/detail/detail_approved_fragment.dart
  22. 20 4
      packages/cpt_form/lib/modules/detail/detail_not_approved_fragment.dart
  23. 23 7
      packages/cpt_form/lib/modules/detail/detail_processing_fragment.dart
  24. 13 7
      packages/cpt_form/lib/modules/detail/form_detail_page.dart
  25. 16 0
      packages/cpt_form/lib/modules/detail/form_detail_state.dart
  26. 22 9
      packages/cpt_form/lib/modules/detail/form_detail_view_model.dart
  27. 1 1
      packages/cpt_form/lib/modules/detail/form_detail_view_model.g.dart
  28. 6 1
      packages/cpt_form/lib/modules/form/apply/form_apply_screen.dart
  29. 3 2
      packages/cpt_form/lib/modules/form/apply/form_apply_state.dart
  30. 28 61
      packages/cpt_form/lib/modules/form/apply/form_apply_view_model.dart
  31. 1 1
      packages/cpt_form/lib/modules/form/apply/form_apply_view_model.g.dart
  32. 7 6
      packages/cpt_form/lib/modules/form/apply/item_form_apply.dart
  33. 7 4
      packages/cpt_form/lib/modules/form/approve/form_approve_screen.dart
  34. 3 2
      packages/cpt_form/lib/modules/form/approve/form_approve_state.dart
  35. 44 67
      packages/cpt_form/lib/modules/form/approve/form_approve_view_model.dart
  36. 1 1
      packages/cpt_form/lib/modules/form/approve/form_approve_view_model.g.dart
  37. 12 8
      packages/cpt_form/lib/modules/form/approve/item_form_approve.dart
  38. 8 8
      packages/cpt_form/lib/modules/form/form_page.dart
  39. 191 189
      packages/cpt_form/lib/modules/form/form_types.dart
  40. 7 1
      packages/cpt_form/lib/modules/form/not_approve/form_not_approve_screen.dart
  41. 3 2
      packages/cpt_form/lib/modules/form/not_approve/form_not_approve_state.dart
  42. 48 70
      packages/cpt_form/lib/modules/form/not_approve/form_not_approve_view_model.dart
  43. 1 1
      packages/cpt_form/lib/modules/form/not_approve/form_not_approve_view_model.g.dart
  44. 13 6
      packages/cpt_form/lib/modules/form/not_approve/item_form_not_approve.dart
  45. 7 1
      packages/cpt_form/lib/modules/form/submit/form_submit_screen.dart
  46. 3 2
      packages/cpt_form/lib/modules/form/submit/form_submit_state.dart
  47. 48 70
      packages/cpt_form/lib/modules/form/submit/form_submit_view_model.dart
  48. 1 1
      packages/cpt_form/lib/modules/form/submit/form_submit_view_model.g.dart
  49. 12 5
      packages/cpt_form/lib/modules/form/submit/item_form_submit.dart
  50. 3 2
      packages/cpt_form/lib/router/page/form_page_router.dart
  51. 42 14
      packages/cpt_form/lib/router/page/form_page_router.gr.dart
  52. 6 9
      packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart
  53. 7 9
      packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart
  54. 51 36
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart
  55. 1 1
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart
  56. 1 1
      packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart
  57. 27 21
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart
  58. 10 7
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart
  59. 22 4
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart
  60. 1 1
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart
  61. 8 9
      packages/cpt_main/lib/modules/feedback/history/feedback_history.dart
  62. 3 2
      packages/cpt_main/lib/modules/feedback/history/feedback_history_state.dart
  63. 48 69
      packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.dart
  64. 1 1
      packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.g.dart
  65. 7 6
      packages/cpt_main/lib/modules/feedback/item_feedback.dart
  66. 7 8
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart
  67. 3 2
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress_state.dart
  68. 51 70
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.dart
  69. 1 1
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.g.dart
  70. 1 1
      packages/cpt_main/lib/modules/main/main_view_model.g.dart
  71. 1 1
      packages/cpt_main/lib/modules/me/me_view_model.g.dart
  72. 5 1
      packages/cpt_main/lib/router/component/main_component_service_impl.dart
  73. 34 5
      packages/cpt_main/lib/router/page/main_page_router.gr.dart
  74. 55 0
      packages/cs_domain/lib/constants/api_constants.dart
  75. 51 0
      packages/cs_domain/lib/entity/feedback_detail_entity.dart
  76. 48 0
      packages/cs_domain/lib/entity/feedback_list_entity.dart
  77. 164 0
      packages/cs_domain/lib/entity/form_content_entity.dart
  78. 31 0
      packages/cs_domain/lib/entity/form_detail_entity.dart
  79. 27 0
      packages/cs_domain/lib/entity/form_list_entity.dart
  80. 23 0
      packages/cs_domain/lib/entity/form_option_entity.dart
  81. 56 0
      packages/cs_domain/lib/entity/form_submitted_entity.dart
  82. 27 0
      packages/cs_domain/lib/entity/form_submitted_page_entity.dart
  83. 64 0
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  84. 140 0
      packages/cs_domain/lib/generated/json/feedback_detail_entity.g.dart
  85. 120 0
      packages/cs_domain/lib/generated/json/feedback_list_entity.g.dart
  86. 227 0
      packages/cs_domain/lib/generated/json/form_content_entity.g.dart
  87. 71 0
      packages/cs_domain/lib/generated/json/form_detail_entity.g.dart
  88. 69 0
      packages/cs_domain/lib/generated/json/form_list_entity.g.dart
  89. 37 0
      packages/cs_domain/lib/generated/json/form_option_entity.g.dart
  90. 137 0
      packages/cs_domain/lib/generated/json/form_submitted_entity.g.dart
  91. 62 0
      packages/cs_domain/lib/generated/json/form_submitted_page_entity.g.dart
  92. 68 0
      packages/cs_domain/lib/repository/facility_repository.dart
  93. 28 0
      packages/cs_domain/lib/repository/facility_repository.g.dart
  94. 324 0
      packages/cs_domain/lib/repository/form_repository.dart
  95. 27 0
      packages/cs_domain/lib/repository/form_repository.g.dart
  96. 123 3
      packages/cs_domain/lib/repository/main_repository.dart
  97. BIN
      packages/cs_resources/assets/facility/active_icon.webp
  98. BIN
      packages/cs_resources/assets/facility/book_icon.webp
  99. BIN
      packages/cs_resources/assets/facility/deposit_icon.webp
  100. 0 0
      packages/cs_resources/assets/facility/function_room_icon.webp

+ 1 - 1
app/lib/main.dart

@@ -42,7 +42,7 @@ void main() async {
   await AppInitializer.initializeRunalone();
 
   //组件路由的注入
-  final serviceManager = ComponentServiceManager()
+  ComponentServiceManager()
     ..addServiceProvider(mainServiceProvider)
     ..addServiceProvider(authServiceProvider)
     ..addServiceProvider(appServiceProvider)

+ 1 - 1
packages/cpt_auth/lib/modules/auth_login/auth_login_page.dart

@@ -121,7 +121,7 @@ class AuthLoginPage extends HookConsumerWidget {
               MyButton(
                 onPressed: viewModel.doLogin,
                 text: S.current.login,
-                isEnabled: state.isLoginBtnEnable,
+                enable: state.isLoginBtnEnable,
                 textColor: Colors.white,
                 disabledTextColor: Colors.white,
                 backgroundColor: context.appColors.btnBgDefault,

+ 9 - 9
packages/cpt_facility/lib/modules/facility/facility_page.dart

@@ -58,8 +58,8 @@ class FacilityPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.facilityBookIcon,
-                      48.5,
-                      40,
+                      36.5,
+                      39.5,
                       S.current.book,
                       tabsRouter.activeIndex == 0,
                     ).onTap(
@@ -70,8 +70,8 @@ class FacilityPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.facilityActiveIcon,
-                      39,
-                      47.5,
+                      35,
+                      46,
                       S.current.facility_active,
                       tabsRouter.activeIndex == 1,
                     ).onTap(
@@ -82,8 +82,8 @@ class FacilityPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.facilityDepositIcon,
-                      35.5,
-                      41.5,
+                      40,
+                      45,
                       S.current.deposit,
                       tabsRouter.activeIndex == 2,
                     ).onTap(
@@ -93,9 +93,9 @@ class FacilityPage extends HookConsumerWidget {
                     ),
                     _buildCategory(
                       context,
-                      Assets.mainLatestPublish,
-                      47.5,
-                      45,
+                      Assets.facilityHistoryIcon,
+                      38,
+                      38,
                       S.current.history,
                       tabsRouter.activeIndex == 3,
                     ).onTap(

+ 52 - 0
packages/cpt_facility/lib/modules/facility/facility_types.dart

@@ -0,0 +1,52 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+
+
+class FacilityTypes {
+  //对应的type类型 对应的icon的图片与宽高
+  static Map<String, Map<String, dynamic>> iconMap = {
+    //Function Room
+    '1': {
+      'name': S.current.function_room,
+      'icon_path': Assets.facilityFunctionRoomIcon,
+      'width': 39.0,
+      'height': 39.5,
+    },
+    //Gourmet Pavilion
+    '2': {
+      'name': S.current.gourmet_pavilion,
+      'icon_path': Assets.facilityGourmetPavilionIcon,
+      'width': 38.0,
+      'height': 33.5,
+    },
+    //Kids Party Room
+    '3': {
+      'name': S.current.kids_party_room,
+      'icon_path': Assets.facilityKidsPartyRoomIcon,
+      'width': 39.0,
+      'height': 39.0,
+    },
+    //Media Room
+    '4': {
+      'name': S.current.media_room,
+      'icon_path': Assets.facilityMediaRoomIcon,
+      'width': 38.5,
+      'height': 38.0,
+    },
+    //Pet Pavilion
+    '5': {
+      'name': S.current.pet_pavilion,
+      'icon_path': Assets.facilityPetPavilionIcon,
+      'width': 38.5,
+      'height': 36.5,
+    },
+    //Tennis Court
+    '6': {
+      'name': S.current.tennis_court,
+      'icon_path': Assets.facilityTennisCourt,
+      'width': 38.5,
+      'height': 38.5,
+    },
+  };
+
+}

+ 20 - 12
packages/cpt_form/lib/modules/apply/attachment_page.dart

@@ -1,4 +1,3 @@
-
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
@@ -6,6 +5,7 @@ import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:plugin_platform/engine/image/image_nine_grid.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
@@ -30,7 +30,6 @@ class AttachmentPage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-
     final viewModel = ref.watch(applyViewModelProvider.notifier);
     final state = ref.watch(applyViewModelProvider);
 
@@ -44,7 +43,7 @@ class AttachmentPage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -70,7 +69,7 @@ class AttachmentPage extends HookConsumerWidget {
 
                         //Note to Management 的文本
                         MyTextView(
-                          state.applyDetail?['detail_data']['attachment_txt'],
+                          state.detailPage?['detail_data']['attachment_txt'],
                           fontSize: 15,
                           marginBottom: 14,
                           isFontRegular: true,
@@ -83,13 +82,11 @@ class AttachmentPage extends HookConsumerWidget {
                           maxImages: 10,
                           spacing: 10,
                           aspectRatio: 108 / 80,
-                          initialImages: const [
-                            "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
-                            "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
-                            "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
-                          ],
+                          initialImages: state.formContentDetail.attachments ?? [],
                           onImagesChanged: (list) {
-
+                            viewModel.updateFormContentDetail((content) {
+                              content.attachments = list;
+                            });
                           },
                         ),
                       ],
@@ -99,7 +96,19 @@ class AttachmentPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: viewModel.gotoNextPage,
+                  onPressed: () {
+
+                    if (state.enableEdit){
+                      final attachments = state.formContentDetail.attachments;
+
+                      if (attachments == null || attachments.isEmpty) {
+                        ToastEngine.show("Select attachments");
+                        return;
+                      }
+                    }
+
+                    viewModel.gotoNextPage();
+                  },
                   text: S.current.next,
                   textColor: Colors.white,
                   backgroundColor: context.appColors.btnBgDefault,
@@ -116,5 +125,4 @@ class AttachmentPage extends HookConsumerWidget {
           return true;
         });
   }
-
 }

+ 138 - 93
packages/cpt_form/lib/modules/apply/form_payment_page.dart

@@ -1,3 +1,6 @@
+import 'dart:typed_data';
+import 'dart:ui';
+
 import 'package:cpt_form/modules/form/apply/form_apply_screen.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
@@ -6,8 +9,11 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -36,16 +42,17 @@ class FormPaymentPage extends HookConsumerWidget {
     final state = ref.watch(applyViewModelProvider);
 
     //签名版配置
-    HandSignatureControl handSignatureControl = HandSignatureControl(
-      threshold: 3.0,
-      smoothRatio: 190 / 345,
-      velocityRange: 2.0,
-    );
+    final HandSignatureControl handSignatureControl = useMemoized(() {
+      return HandSignatureControl(
+        threshold: 3.0,
+        smoothRatio: 190 / 345,
+        velocityRange: 2.0,
+      );
+    });
 
     useEffect(() {
       //赋值State的值
       Future.microtask(() {});
-
       return () {
         // 释放控制器资源
       };
@@ -53,7 +60,7 @@ class FormPaymentPage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -68,96 +75,114 @@ class FormPaymentPage extends HookConsumerWidget {
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         //支付
-                        Row(
-                          children: [
-                            const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
-                            MyTextView(
-                              S.current.payment,
-                              textColor: context.appColors.textBlack,
-                              fontSize: 17,
-                              marginLeft: 14,
-                              isFontMedium: true,
-                            ).expanded(),
-                          ],
-                        ).marginOnly(top: 15, left: 15, right: 15),
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.price > 0,
+                          child: Row(
+                            children: [
+                              const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
+                              MyTextView(
+                                S.current.payment,
+                                textColor: context.appColors.textBlack,
+                                fontSize: 17,
+                                marginLeft: 14,
+                                isFontMedium: true,
+                              ).expanded(),
+                            ],
+                          ).marginOnly(top: 15, left: 15, right: 15),
+                        ),
 
-                        //金额
-                        Row(
-                          mainAxisSize: MainAxisSize.max,
-                          children: [
-                            MyTextView(
-                              S.current.fee,
-                              textColor: context.appColors.textBlack,
-                              fontSize: 18,
-                              isFontRegular: true,
-                            ),
-                            const Spacer(),
-                            MyTextView(
-                              "SGD",
-                              textColor: context.appColors.textBlack,
-                              fontSize: 18,
-                              isFontRegular: true,
-                            ),
-                            MyTextView(
-                              "\$21.80",
-                              textColor: context.appColors.textPrimary,
-                              fontSize: 22,
-                              marginLeft: 8,
-                              isFontMedium: true,
-                            ),
-                          ],
-                        ).marginOnly(top: 20, left: 15, right: 15, bottom: 20),
+                        //支付金额
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.price > 0,
+                          child: Row(
+                            mainAxisSize: MainAxisSize.max,
+                            children: [
+                              MyTextView(
+                                S.current.fee,
+                                textColor: context.appColors.textBlack,
+                                fontSize: 18,
+                                isFontRegular: true,
+                              ),
+                              const Spacer(),
+                              MyTextView(
+                                "SGD",
+                                textColor: context.appColors.textBlack,
+                                fontSize: 18,
+                                isFontRegular: true,
+                              ),
+                              MyTextView(
+                                "\$${state.formItem?.price ?? 0}",
+                                textColor: context.appColors.textPrimary,
+                                fontSize: 22,
+                                marginLeft: 8,
+                                isFontMedium: true,
+                              ),
+                            ],
+                          ).marginOnly(top: 20, left: 15, right: 15, bottom: 20),
+                        ),
 
                         //分割线
-                        Divider(
-                          color: context.appColors.dividerDefault,
-                          height: 0.5,
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.price > 0,
+                          child: Divider(
+                            color: context.appColors.dividerDefault,
+                            height: 0.5,
+                          ),
                         ),
 
                         //押金
-                        Row(
-                          children: [
-                            const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
-                            MyTextView(
-                              S.current.deposit,
-                              textColor: context.appColors.textBlack,
-                              fontSize: 17,
-                              marginLeft: 14,
-                              isFontMedium: true,
-                            ).expanded(),
-                          ],
-                        ).marginOnly(top: 15, left: 15, right: 15),
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.deposit > 0,
+                          child: Row(
+                            children: [
+                              const MyAssetImage(Assets.paymentInfoDetails, width: 27, height: 27),
+                              MyTextView(
+                                S.current.deposit,
+                                textColor: context.appColors.textBlack,
+                                fontSize: 17,
+                                marginLeft: 14,
+                                isFontMedium: true,
+                              ).expanded(),
+                            ],
+                          ).marginOnly(top: 15, left: 15, right: 15),
+                        ),
 
                         //押金金额
-                        Row(
-                          children: [
-                            MyTextView(
-                              S.current.deposit_hold,
-                              textColor: context.appColors.textBlack,
-                              fontSize: 18,
-                              isFontRegular: true,
-                            ),
-                            const Spacer(),
-                            MyTextView(
-                              "SGD",
-                              textColor: context.appColors.textBlack,
-                              fontSize: 18,
-                              isFontRegular: true,
-                            ),
-                            MyTextView(
-                              "\$1000.00",
-                              textColor: context.appColors.textPrimary,
-                              fontSize: 22,
-                              marginLeft: 8,
-                              isFontMedium: true,
-                            ),
-                          ],
-                        ).marginOnly(top: 20, left: 15, right: 15, bottom: 20),
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.deposit > 0,
+                          child: Row(
+                            children: [
+                              MyTextView(
+                                S.current.deposit_hold,
+                                textColor: context.appColors.textBlack,
+                                fontSize: 18,
+                                isFontRegular: true,
+                              ),
+                              const Spacer(),
+                              MyTextView(
+                                "SGD",
+                                textColor: context.appColors.textBlack,
+                                fontSize: 18,
+                                isFontRegular: true,
+                              ),
+                              MyTextView(
+                                "\$${state.formItem?.deposit ?? 0}",
+                                textColor: context.appColors.textPrimary,
+                                fontSize: 22,
+                                marginLeft: 8,
+                                isFontMedium: true,
+                              ),
+                            ],
+                          ).marginOnly(top: 20, left: 15, right: 15, bottom: 20),
+                        ),
 
                         //分割线
-                        Divider(
-                          color: context.appColors.dividerDefault,
-                          height: 0.5,
+                        Visibility(
+                          visible: state.formItem != null && state.formItem!.deposit > 0,
+                          child: Divider(
+                            color: context.appColors.dividerDefault,
+                            height: 0.5,
+                          ),
                         ),
 
                         //银行卡
@@ -190,7 +215,7 @@ class FormPaymentPage extends HookConsumerWidget {
 
                         //签名的说明文本
                         MyTextView(
-                          state.applyDetail?['detail_data']['signature_txt'],
+                          state.detailPage?['detail_data']['signature_txt'],
                           fontSize: 15,
                           marginTop: 18,
                           marginLeft: 15,
@@ -202,7 +227,8 @@ class FormPaymentPage extends HookConsumerWidget {
 
                         //签名框
                         Center(
-                          child: GestureDetector(  //处理手势冲突,手指在签名版上的时候不滑动父布局
+                          child: GestureDetector(
+                              //处理手势冲突,手指在签名版上的时候不滑动父布局
                               behavior: HitTestBehavior.opaque,
                               onVerticalDragUpdate: (_) {},
                               child: Stack(
@@ -258,11 +284,11 @@ class FormPaymentPage extends HookConsumerWidget {
                                 text: S.current.signed_and_agreed_by,
                               ),
                               TextSpan(
-                                text: " Wu Bing Bing ",
+                                text: " ${UserConfigService.getState().userName ?? "-"} \n",
                                 style: TextStyle(color: context.appColors.textPrimary),
                               ),
                               TextSpan(
-                                text: " 21 Nov 2024, 03:08 PM",
+                                text: DateTimeUtils.formatNowDateStr(format: 'dd MMM yyyy HH:mm'),
                               ),
                             ],
                           ),
@@ -274,8 +300,27 @@ class FormPaymentPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: () {
-                    viewModel.gotoNextPage();
+                  onPressed: () async{
+                    final isFilled = handSignatureControl.isFilled;
+                    if (!isFilled) {
+                      ToastEngine.show("Please sign first");
+                      return;
+                    }
+
+                    var byteData = await handSignatureControl.toImage(
+                      format: ImageByteFormat.png,
+                      border: 0,
+                      width: 345,
+                      height: 190,
+                      background: Colors.white,
+                    ) as ByteData;
+
+                    //存入本表单数据
+                    viewModel.updateFormContentDetail((content) {
+                      content.signatureByteData = byteData;
+                    });
+
+                    viewModel.submitForm();
                   },
                   text: S.current.next,
                   textColor: Colors.white,

+ 33 - 8
packages/cpt_form/lib/modules/apply/form_terms_page.dart

@@ -1,5 +1,7 @@
 import 'package:cpt_form/modules/apply/vm/apply_view_model.dart';
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/form_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
@@ -12,15 +14,38 @@ import '../../router/page/form_page_router.dart';
 @RoutePage()
 class FormTermsPage extends HookConsumerWidget {
   final String type;
+  final String? estateFormId;
+  final FormListEntity? formItem;
+  final bool enableEdit;
+  final FormContentEntity? formContent;
 
-  const FormTermsPage({Key? key, @PathParam() required this.type}) : super(key: key);
+  const FormTermsPage({Key? key, required this.type, this.estateFormId, this.formItem, required this.enableEdit, this.formContent}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context, required String formType}) {
+  static void startInstance({
+    BuildContext? context,
+    required String formType,
+    String? estateFormId,
+    FormListEntity? formItem,
+    required bool enableEdit,
+    FormContentEntity? formContent,
+  }) {
     if (context != null) {
-      context.router.push(FormTermsPageRoute(type: formType));
+      context.router.push(FormTermsPageRoute(
+        type: formType,
+        formItem: formItem,
+        enableEdit: enableEdit,
+        formContent: formContent,
+        estateFormId: estateFormId,
+      ));
     } else {
-      appRouter.push(FormTermsPageRoute(type: formType));
+      appRouter.push(FormTermsPageRoute(
+        type: formType,
+        formItem: formItem,
+        enableEdit: enableEdit,
+        formContent: formContent,
+        estateFormId: estateFormId,
+      ));
     }
   }
 
@@ -31,17 +56,17 @@ class FormTermsPage extends HookConsumerWidget {
 
     useEffect(() {
       // 组件挂载时执行 - 执行接口请求
-      Future.microtask(() => viewModel.setFormType(type));
+      Future.microtask(() => viewModel.setFormType(type, estateFormId, formItem, enableEdit, formContent));
       return () {
         // 组件卸载时执行
       };
     }, []);
 
-    return state.applyDetail != null
+    return state.detailPage != null
         ? WebViewPage(
             showAppbar: true,
-            initialUrl: state.applyDetail?['term_url'],
-            arguments: {'title': state.applyDetail?['title']},
+            initialUrl: state.detailPage?['term_url'],
+            arguments: {'title': state.detailPage?['title']},
             bottomBtnTxt: S.current.next,
             bottomBtnAction: viewModel.gotoNextPage,
           )

+ 68 - 24
packages/cpt_form/lib/modules/apply/guest_vehicle_page.dart

@@ -6,6 +6,8 @@ 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:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -47,24 +49,19 @@ class GuestVehiclePage extends HookConsumerWidget {
 
     useEffect(() {
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        vehicleNumController.text = state.formContentDetail.vehicleNumber ?? "";
+        vehicleInfoController.text = state.formContentDetail.vehicleMakeModelColour ?? "";
+        guestNameController.text = state.formContentDetail.guestName ?? "";
+        guestPhoneController.text = state.formContentDetail.guestMobileNumber ?? "";
+      });
 
-      return () {
-        // 释放控制器资源
-        vehicleNumController.dispose();
-        vehicleInfoController.dispose();
-        guestNameController.dispose();
-        guestPhoneController.dispose();
-        vehicleNumFocusNode.dispose();
-        vehicleInfoFocusNode.dispose();
-        guestNameFocusNode.dispose();
-        guestPhoneFocusNode.dispose();
-      };
+      return () {};
     }, []);
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -79,21 +76,22 @@ class GuestVehiclePage extends HookConsumerWidget {
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         //下拉选 - 访问时间
-                        MyTextView(
-                          S.current.date_of_entry,
-                          fontSize: 17,
-                          marginTop: 30,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.date_of_entry,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 30, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_date,
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.dateOfEntry,
                           onClick: () {
                             viewModel.pickDate(null, (date) {
-                              ToastEngine.show("选择的日期:$date");
+                              viewModel.updateFormContentDetail((content) {
+                                content.dateOfEntry = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
@@ -110,6 +108,7 @@ class GuestVehiclePage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "vehicle_num",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: vehicleNumController,
@@ -132,6 +131,7 @@ class GuestVehiclePage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "vehicle_info",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: vehicleInfoController,
@@ -154,6 +154,7 @@ class GuestVehiclePage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "guest_name",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: guestNameController,
@@ -176,6 +177,7 @@ class GuestVehiclePage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "guest_phone",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.phone,
                           textInputAction: TextInputAction.done,
                           controller: guestPhoneController,
@@ -184,7 +186,6 @@ class GuestVehiclePage extends HookConsumerWidget {
                             guestPhoneFocusNode.unfocus();
                           },
                         ),
-
                       ],
                     ),
                   ),
@@ -198,6 +199,49 @@ class GuestVehiclePage extends HookConsumerWidget {
                     guestNameFocusNode.unfocus();
                     guestPhoneFocusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? vehicleNumber = vehicleNumController.text;
+                      String? vehicleMakeModelColour = vehicleInfoController.text;
+                      String? guestName = guestNameController.text;
+                      String? guestMobileNumber = guestPhoneController.text;
+
+                      //校验数据
+                      final dateOfEntry = state.formContentDetail.dateOfEntry;
+
+                      if (Utils.isEmpty(dateOfEntry)) {
+                        ToastEngine.show("Select date of entry");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(vehicleNumber)) {
+                        ToastEngine.show("Enter vehicle number");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(vehicleMakeModelColour)) {
+                        ToastEngine.show("Enter vehicle make/model/ colour");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(guestName)) {
+                        ToastEngine.show("Enter guest name");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(guestMobileNumber)) {
+                        ToastEngine.show("Enter guest mobile number");
+                        return;
+                      }
+
+                      //存入本表单数据
+                      viewModel.updateFormContentDetail((content) {
+                        content.vehicleNumber = vehicleNumber;
+                        content.vehicleMakeModelColour = vehicleMakeModelColour;
+                        content.guestName = guestName;
+                        content.guestMobileNumber = guestMobileNumber;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,
@@ -226,7 +270,7 @@ class GuestVehiclePage extends HookConsumerWidget {
     TextInputType textInputType = TextInputType.text,
     String? errorText,
     bool obscureText = false,
-    required TextEditingController controller,
+    required TextEditingController? controller,
     required FocusNode focusNode,
     bool enable = true,
     TextInputAction textInputAction = TextInputAction.done,

+ 24 - 14
packages/cpt_form/lib/modules/apply/large_text_box_page.dart

@@ -1,11 +1,12 @@
-
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -13,6 +14,7 @@ import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 import '../../router/page/form_page_router.dart';
 import 'vm/apply_view_model.dart';
+
 @RoutePage()
 class LargeTextBoxPage extends HookConsumerWidget {
   const LargeTextBoxPage({Key? key}) : super(key: key);
@@ -37,19 +39,16 @@ class LargeTextBoxPage extends HookConsumerWidget {
 
     useEffect(() {
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        textEditingController.text = state.formContentDetail.listOfRenovationWorks ?? "";
+      });
 
-      return () {
-        // 释放控制器资源
-        textEditingController.dispose();
-        focusNode.dispose();
-      };
+      return () {};
     }, []);
 
-
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -65,7 +64,7 @@ class LargeTextBoxPage extends HookConsumerWidget {
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         MyTextView(
-                          state.applyDetail?['detail_data']['large_txt'],
+                          state.detailPage?['detail_data']['large_txt'],
                           fontSize: 17,
                           marginTop: 30,
                           marginBottom: 17,
@@ -86,7 +85,7 @@ class LargeTextBoxPage extends HookConsumerWidget {
                               cursorColor: context.appColors.authFiledText,
                               cursorWidth: 1.5,
                               autofocus: false,
-                              enabled: true,
+                              enabled: state.enableEdit,
                               focusNode: focusNode,
                               controller: textEditingController,
                               decoration: InputDecoration(
@@ -113,7 +112,6 @@ class LargeTextBoxPage extends HookConsumerWidget {
                               expands: true,
                               onChanged: (text) {
                                 // 当文本改变时
-
                               },
                             ),
                           ),
@@ -125,9 +123,21 @@ class LargeTextBoxPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: (){
+                  onPressed: () {
                     focusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? listOfRenovationWorks = textEditingController.text;
+                      if (Utils.isEmpty(listOfRenovationWorks)) {
+                        ToastEngine.show("Enter List Of Renovation Works");
+                        return;
+                      }
+
+                      viewModel.updateFormContentDetail((content) {
+                        content.listOfRenovationWorks = listOfRenovationWorks;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,
@@ -146,4 +156,4 @@ class LargeTextBoxPage extends HookConsumerWidget {
           return true;
         });
   }
-}
+}

+ 44 - 13
packages/cpt_form/lib/modules/apply/moving_company_page.dart

@@ -4,7 +4,9 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -45,26 +47,22 @@ class MovingCompanyPage extends HookConsumerWidget {
     final addressFocusNode = useFocusNode();
 
     useEffect(() {
-
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        companyController.text = state.formContentDetail.movingCompany ?? "";
+        contactController.text = state.formContentDetail.personInCharge ?? "";
+        phoneController.text = state.formContentDetail.mobileNumber ?? "";
+        addressController.text = state.formContentDetail.companyAddress ?? "";
+      });
 
       return () {
         // 释放控制器资源
-        companyController.dispose();
-        contactController.dispose();
-        phoneController.dispose();
-        addressController.dispose();
-        companyFocusNode.dispose();
-        contactFocusNode.dispose();
-        phoneFocusNode.dispose();
-        addressFocusNode.dispose();
       };
     }, []);
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -90,6 +88,7 @@ class MovingCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "company",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: companyController,
@@ -112,6 +111,7 @@ class MovingCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "contact",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: contactController,
@@ -134,6 +134,7 @@ class MovingCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "phone",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.phone,
                           textInputAction: TextInputAction.next,
                           controller: phoneController,
@@ -170,7 +171,7 @@ class MovingCompanyPage extends HookConsumerWidget {
                               cursorColor: context.appColors.authFiledText,
                               cursorWidth: 1.5,
                               autofocus: false,
-                              enabled: true,
+                              enabled: state.enableEdit,
                               focusNode: addressFocusNode,
                               controller: addressController,
                               decoration: InputDecoration(
@@ -207,12 +208,42 @@ class MovingCompanyPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: (){
+                  onPressed: () {
                     companyFocusNode.unfocus();
                     contactFocusNode.unfocus();
                     phoneFocusNode.unfocus();
                     addressFocusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? movingCompany = companyController.text;
+                      String? personInCharge = contactController.text;
+                      String? mobileNumber = phoneController.text;
+                      String? companyAddress = addressController.text;
+
+                      if (Utils.isEmpty(movingCompany)) {
+                        ToastEngine.show("Enter Moving Company");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(personInCharge)) {
+                        ToastEngine.show("Enter Person In Charge");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(mobileNumber)) {
+                        ToastEngine.show("Enter Mobile Number");
+                        return;
+                      }
+
+                      //存入本表单数据
+                      viewModel.updateFormContentDetail((content) {
+                        content.movingCompany = movingCompany;
+                        content.personInCharge = personInCharge;
+                        content.mobileNumber = mobileNumber;
+                        content.companyAddress = companyAddress;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,

+ 55 - 30
packages/cpt_form/lib/modules/apply/moving_date_page.dart

@@ -1,4 +1,3 @@
-
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
@@ -7,13 +6,17 @@ 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:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/form_require_text.dart';
 import 'package:widgets/shatter/picker_container.dart';
 import '../../router/page/form_page_router.dart';
 import 'vm/apply_view_model.dart';
+
 @RoutePage()
 class MovingDatePage extends HookConsumerWidget {
   const MovingDatePage({Key? key}) : super(key: key);
@@ -43,7 +46,7 @@ class MovingDatePage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -57,43 +60,44 @@ class MovingDatePage extends HookConsumerWidget {
                       mainAxisSize: MainAxisSize.max,
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
-
                         //下拉选 - 开始时间
-                        MyTextView(
-                          S.current.start_date_caps,
-                          fontSize: 17,
-                          marginTop: 30,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.start_date_caps,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 30, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.startDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.startDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
 
                         //下拉选 - 结束时间
-                        MyTextView(
-                          S.current.end_date_caps,
-                          fontSize: 17,
-                          marginTop: 14,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.end_date_caps,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.endDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.endDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
@@ -111,13 +115,16 @@ class MovingDatePage extends HookConsumerWidget {
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.timeOrArrival,
+                          onClick: () {
+                            viewModel.pickTime(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.timeOrArrival = DateTimeUtils.formatDate(date, format: 'HH:mm');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
-
                       ],
                     ),
                   ),
@@ -125,7 +132,25 @@ class MovingDatePage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: viewModel.gotoNextPage,
+                  onPressed: () {
+                    if (state.enableEdit) {
+                      //校验数据
+                      final startDate = state.formContentDetail.startDate;
+                      final endDate = state.formContentDetail.endDate;
+
+                      if (Utils.isEmpty(startDate)) {
+                        ToastEngine.show("Select Start Date");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(endDate)) {
+                        ToastEngine.show("Select End Date");
+                        return;
+                      }
+                    }
+
+                    viewModel.gotoNextPage();
+                  },
                   text: S.current.next,
                   textColor: Colors.white,
                   backgroundColor: context.appColors.btnBgDefault,

+ 23 - 12
packages/cpt_form/lib/modules/apply/note_management_page.dart

@@ -4,7 +4,9 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -37,19 +39,16 @@ class NoteManagementPage extends HookConsumerWidget {
 
     useEffect(() {
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        textEditingController.text = state.formContentDetail.notesToManagement ?? "";
+      });
 
-      return () {
-        // 释放控制器资源
-        textEditingController.dispose();
-        focusNode.dispose();
-      };
+      return () {};
     }, []);
 
-
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -75,7 +74,7 @@ class NoteManagementPage extends HookConsumerWidget {
 
                         //Note to Management 的文本
                         MyTextView(
-                          state.applyDetail?['detail_data']['note_management_txt'],
+                          state.detailPage?['detail_data']['note_management_txt'],
                           fontSize: 15,
                           marginBottom: 18,
                           isFontRegular: true,
@@ -95,7 +94,7 @@ class NoteManagementPage extends HookConsumerWidget {
                               cursorColor: context.appColors.authFiledText,
                               cursorWidth: 1.5,
                               autofocus: false,
-                              enabled: true,
+                              enabled: state.enableEdit,
                               focusNode: focusNode,
                               controller: textEditingController,
                               decoration: InputDecoration(
@@ -122,7 +121,6 @@ class NoteManagementPage extends HookConsumerWidget {
                               expands: true,
                               onChanged: (text) {
                                 // 当文本改变时
-
                               },
                             ),
                           ),
@@ -134,9 +132,22 @@ class NoteManagementPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: (){
+                  onPressed: () {
                     focusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? notesToManagement = textEditingController.text;
+
+                      if (Utils.isEmpty(notesToManagement)) {
+                        ToastEngine.show("Enter Notes To Management");
+                        return;
+                      }
+
+                      viewModel.updateFormContentDetail((content) {
+                        content.notesToManagement = notesToManagement;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,

+ 44 - 14
packages/cpt_form/lib/modules/apply/renovation_company_page.dart

@@ -4,7 +4,9 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -46,24 +48,19 @@ class RenovationCompanyPage extends HookConsumerWidget {
 
     useEffect(() {
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        companyController.text = state.formContentDetail.renovationCompany ?? "";
+        contactController.text = state.formContentDetail.personInCharge ?? "";
+        phoneController.text = state.formContentDetail.mobileNumber ?? "";
+        addressController.text = state.formContentDetail.companyAddress ?? "";
+      });
 
-      return () {
-        // 释放控制器资源
-        companyController.dispose();
-        contactController.dispose();
-        phoneController.dispose();
-        addressController.dispose();
-        companyFocusNode.dispose();
-        contactFocusNode.dispose();
-        phoneFocusNode.dispose();
-        addressFocusNode.dispose();
-      };
+      return () {};
     }, []);
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -89,6 +86,7 @@ class RenovationCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "company",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: companyController,
@@ -111,6 +109,7 @@ class RenovationCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "contact",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: contactController,
@@ -133,6 +132,7 @@ class RenovationCompanyPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "phone",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.phone,
                           textInputAction: TextInputAction.next,
                           controller: phoneController,
@@ -169,7 +169,7 @@ class RenovationCompanyPage extends HookConsumerWidget {
                               cursorColor: context.appColors.authFiledText,
                               cursorWidth: 1.5,
                               autofocus: false,
-                              enabled: true,
+                              enabled: state.enableEdit,
                               focusNode: addressFocusNode,
                               controller: addressController,
                               decoration: InputDecoration(
@@ -212,6 +212,36 @@ class RenovationCompanyPage extends HookConsumerWidget {
                     phoneFocusNode.unfocus();
                     addressFocusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? renovationCompany = companyController.text;
+                      String? personInCharge = contactController.text;
+                      String? mobileNumber = phoneController.text;
+                      String? companyAddress = addressController.text;
+
+                      if (Utils.isEmpty(renovationCompany)) {
+                        ToastEngine.show("Enter Renovation Company");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(personInCharge)) {
+                        ToastEngine.show("Enter Person In Charge");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(mobileNumber)) {
+                        ToastEngine.show("Enter Mobile Number");
+                        return;
+                      }
+
+                      //存入本表单数据
+                      viewModel.updateFormContentDetail((content) {
+                        content.renovationCompany = renovationCompany;
+                        content.personInCharge = personInCharge;
+                        content.mobileNumber = mobileNumber;
+                        content.companyAddress = companyAddress;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,

+ 61 - 33
packages/cpt_form/lib/modules/apply/renovation_date_page.dart

@@ -1,4 +1,3 @@
-
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
@@ -7,10 +6,13 @@ 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:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/form_require_text.dart';
 import 'package:widgets/shatter/picker_container.dart';
 import '../../router/page/form_page_router.dart';
 import 'vm/apply_view_model.dart';
@@ -44,7 +46,7 @@ class RenovationDatePage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -58,43 +60,44 @@ class RenovationDatePage extends HookConsumerWidget {
                       mainAxisSize: MainAxisSize.max,
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
-
                         //下拉选 - 开始时间
-                        MyTextView(
-                          S.current.renovation_start_date,
-                          fontSize: 17,
-                          marginTop: 30,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.renovation_start_date,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 30, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.renovationStartDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.renovationStartDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
 
                         //下拉选 - 结束时间
-                        MyTextView(
-                          S.current.renovation_end_date,
-                          fontSize: 17,
-                          marginTop: 14,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.renovation_end_date,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.renovationEndDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.renovationEndDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
@@ -112,9 +115,13 @@ class RenovationDatePage extends HookConsumerWidget {
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.hackingStartDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.hackingStartDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
@@ -132,13 +139,16 @@ class RenovationDatePage extends HookConsumerWidget {
 
                         PickerContainer(
                           hint: S.current.choose_date,
-                          onClick: (){
-                            viewModel.pickDate(null,(date){
-                              ToastEngine.show("选择的日期:$date");
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.hackingEndDate,
+                          onClick: () {
+                            viewModel.pickDate(null, (date) {
+                              viewModel.updateFormContentDetail((content) {
+                                content.hackingEndDate = DateTimeUtils.formatDate(date, format: 'yyyy-MM-dd');
+                              });
                             });
                           },
                         ).marginOnly(left: 15, right: 15),
-
                       ],
                     ),
                   ),
@@ -146,7 +156,25 @@ class RenovationDatePage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: viewModel.gotoNextPage,
+                  onPressed: () {
+                    if (state.enableEdit) {
+                      //校验数据
+                      final startDate = state.formContentDetail.renovationEndDate;
+                      final endDate = state.formContentDetail.renovationEndDate;
+
+                      if (Utils.isEmpty(startDate)) {
+                        ToastEngine.show("Select Renovation Start Date");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(endDate)) {
+                        ToastEngine.show("Select Renovation End Date");
+                        return;
+                      }
+                    }
+
+                    viewModel.gotoNextPage();
+                  },
                   text: S.current.next,
                   textColor: Colors.white,
                   backgroundColor: context.appColors.btnBgDefault,

+ 75 - 34
packages/cpt_form/lib/modules/apply/signature_page.dart

@@ -1,3 +1,5 @@
+import 'dart:typed_data';
+import 'dart:ui';
 
 import 'package:cpt_form/modules/apply/vm/apply_view_model.dart';
 import 'package:cs_resources/generated/l10n.dart';
@@ -6,10 +8,15 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_basic/provider/user_config/user_config_service.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 import '../../router/page/form_page_router.dart';
@@ -33,11 +40,13 @@ class SignaturePage extends HookConsumerWidget {
     final state = ref.watch(applyViewModelProvider);
 
     //签名版配置
-    HandSignatureControl handSignatureControl = HandSignatureControl(
-      threshold: 3.0,
-      smoothRatio: 190 / 345,
-      velocityRange: 2.0,
-    );
+    final HandSignatureControl handSignatureControl = useMemoized(() {
+      return HandSignatureControl(
+        threshold: 3.0,
+        smoothRatio: 190 / 345,
+        velocityRange: 2.0,
+      );
+    });
 
     useEffect(() {
       //赋值State的值
@@ -51,7 +60,7 @@ class SignaturePage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -76,7 +85,7 @@ class SignaturePage extends HookConsumerWidget {
 
                         //签名的说明文本
                         MyTextView(
-                          state.applyDetail?['detail_data']['signature_txt'],
+                          state.detailPage?['detail_data']['signature_txt'],
                           fontSize: 15,
                           marginTop: 26,
                           marginBottom: 21,
@@ -93,33 +102,42 @@ class SignaturePage extends HookConsumerWidget {
                                 width: 345,
                                 height: 190,
                                 color: context.appColors.imgGrayBg,
-                                child: HandSignature(
-                                  control: handSignatureControl,
-                                  color: context.appColors.textBlack,
-                                  width: 1.0,
-                                  maxWidth: 3.5,
-                                  type: SignatureDrawType.shape,
-                                ),
+                                child: state.enableEdit
+                                    ? HandSignature(
+                                        control: handSignatureControl,
+                                        color: context.appColors.textBlack,
+                                        width: 1.0,
+                                        maxWidth: 3.5,
+                                        type: SignatureDrawType.shape,
+                                      )
+                                    : MyLoadImage(
+                                        state.formContentDetail.signature,
+                                        width: 345,
+                                        height: 190,
+                                      ),
                               ),
                             ),
 
                             //清除签名
                             Align(
                               alignment: Alignment.bottomRight,
-                              child: MyTextView(
-                                S.current.clean,
-                                fontSize: 12,
-                                textColor: Colors.white,
-                                cornerRadius: 10.37,
-                                backgroundColor: context.appColors.btnBgDefault,
-                                paddingTop: 4,
-                                paddingBottom: 4,
-                                paddingLeft: 11,
-                                paddingRight: 11,
-                                margin: 10,
-                                onClick: () {
-                                  handSignatureControl.clear();
-                                },
+                              child: Visibility(
+                                visible: state.enableEdit,
+                                child: MyTextView(
+                                  S.current.clean,
+                                  fontSize: 12,
+                                  textColor: Colors.white,
+                                  cornerRadius: 10.37,
+                                  backgroundColor: context.appColors.btnBgDefault,
+                                  paddingTop: 4,
+                                  paddingBottom: 4,
+                                  paddingLeft: 11,
+                                  paddingRight: 11,
+                                  margin: 10,
+                                  onClick: () {
+                                    handSignatureControl.clear();
+                                  },
+                                ),
                               ),
                             ),
                           ],
@@ -128,24 +146,24 @@ class SignaturePage extends HookConsumerWidget {
                           height: 190,
                         ),
 
+                        //同意协议富文本
                         RichText(
                           text: TextSpan(
-                            style: TextStyle(fontSize: 15, fontWeight:  FontWeight.w400, color: context.appColors.textBlack),
+                            style: TextStyle(fontSize: 15, fontWeight: FontWeight.w400, color: context.appColors.textBlack),
                             children: <TextSpan>[
                               TextSpan(
                                 text: S.current.signed_and_agreed_by,
                               ),
                               TextSpan(
-                                text: " Wu Bing Bing ",
+                                text: " ${UserConfigService.getState().userName ?? "-"} \n",
                                 style: TextStyle(color: context.appColors.textPrimary),
                               ),
                               TextSpan(
-                                text: " 21 Nov 2024, 03:08 PM",
+                                text: DateTimeUtils.formatNowDateStr(format: 'dd MMM yyyy HH:mm'),
                               ),
                             ],
                           ),
-                        ).marginOnly(top: 21,bottom: 21),
-
+                        ).marginOnly(top: 21, bottom: 21),
                       ],
                     ),
                   ),
@@ -153,11 +171,34 @@ class SignaturePage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: viewModel.gotoNextPage,
+                  onPressed: () async {
+                    final isFilled = handSignatureControl.isFilled;
+                    if (!isFilled) {
+                      ToastEngine.show("Please sign first");
+                      return;
+                    }
+
+                    var byteData = await handSignatureControl.toImage(
+                      format: ImageByteFormat.png,
+                      border: 0,
+                      width: 345,
+                      height: 190,
+                      background: Colors.white,
+                    ) as ByteData;
+
+                    //存入本表单数据
+                    viewModel.updateFormContentDetail((content) {
+                      content.signatureByteData = byteData;
+                    });
+
+                    viewModel.submitForm();
+                  },
                   text: S.current.submit,
                   textColor: Colors.white,
                   backgroundColor: context.appColors.btnBgDefault,
                   fontWeight: FontWeight.w500,
+                  enable: state.enableEdit,
+                  disabledBackgroundColor: context.appColors.disEnableGray,
                   type: ClickType.throttle,
                   fontSize: 16,
                   minHeight: 50,

+ 21 - 3
packages/cpt_form/lib/modules/apply/type_of_application_page.dart

@@ -3,8 +3,10 @@ import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
 import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -33,7 +35,7 @@ class TypeOfApplicationPage extends HookConsumerWidget {
 
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -50,14 +52,30 @@ class TypeOfApplicationPage extends HookConsumerWidget {
 
                 PickerContainer(
                   hint: S.current.choose_an_option,
-                  onClick: viewModel.pickOption,
+                  enable: state.enableEdit,
+                  content: state.formContentDetail.typeOfApplication,
+                  onClick: () {
+                    viewModel.pickOption(true);
+                  },
                 ).marginOnly(left: 15, right: 15),
 
                 const Spacer(),
 
                 //底部按钮
                 MyButton(
-                  onPressed: viewModel.gotoNextPage,
+                  onPressed: (){
+                    if (state.enableEdit){
+                      //校验数据
+                      final typeOfApplication = state.formContentDetail.typeOfApplication;
+
+                      if (Utils.isEmpty(typeOfApplication)) {
+                        ToastEngine.show("Select Type Of Application");
+                        return;
+                      }
+                    }
+
+                    viewModel.gotoNextPage();
+                  },
                   text: S.current.next,
                   textColor: Colors.white,
                   backgroundColor: context.appColors.btnBgDefault,

+ 87 - 55
packages/cpt_form/lib/modules/apply/vehicle_info_page.dart

@@ -1,4 +1,3 @@
-
 import 'package:cpt_form/modules/apply/vm/apply_view_model.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
@@ -6,7 +5,9 @@ import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -43,27 +44,20 @@ class VehicleInfoPage extends HookConsumerWidget {
     final FocusNode iuNumFocusNode = useFocusNode();
     final FocusNode vehicleInfoFocusNode = useFocusNode();
 
-
     useEffect(() {
-
       //赋值State的值
-      Future.microtask(() {});
+      Future.microtask(() {
+        vehicleNumController.text = state.formContentDetail.vehicleNumber ?? "";
+        iuNumController.text = state.formContentDetail.iuNumber ?? "";
+        vehicleInfoController.text = state.formContentDetail.vehicleMakeModelColour ?? "";
+      });
 
-      return () {
-        // 释放控制器资源
-        vehicleNumController.dispose();
-        iuNumController.dispose();
-        vehicleInfoController.dispose();
-        vehicleNumFocusNode.dispose();
-        iuNumFocusNode.dispose();
-        vehicleInfoFocusNode.dispose();
-      };
+      return () {};
     }, []);
 
-
     return WillPopScope(
         child: Scaffold(
-            appBar: MyAppBar.appBar(context, state.applyDetail?['title']),
+            appBar: MyAppBar.appBar(context, state.detailPage?['title']),
             backgroundColor: context.appColors.backgroundWhite,
             body: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
@@ -77,52 +71,53 @@ class VehicleInfoPage extends HookConsumerWidget {
                       mainAxisSize: MainAxisSize.max,
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
-
                         //下拉选 - Type类型
-                        MyTextView(
-                          S.current.type_of_application,
-                          fontSize: 17,
-                          marginTop: 30,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.type_of_application,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 30, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_an_option,
-                          onClick: viewModel.pickOption,
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.typeOfApplication,
+                          onClick: () {
+                            viewModel.pickOption(true);
+                          },
                         ).marginOnly(left: 15, right: 15),
 
                         //下拉选 - 所有权状态
-                        MyTextView(
-                          S.current.ownership_status,
-                          fontSize: 17,
-                          marginTop: 14,
-                          marginLeft: 15,
-                          marginBottom: 16,
-                          isFontMedium: true,
+                        FormRequireText(
+                          text: S.current.ownership_status,
                           textColor: context.appColors.textBlack,
-                        ),
+                          fontSize: 17,
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
 
                         PickerContainer(
                           hint: S.current.choose_an_option,
-                          onClick: viewModel.pickOption,
+                          enable: state.enableEdit,
+                          content: state.formContentDetail.ownershipStatus,
+                          onClick: () {
+                            viewModel.pickOption(false);
+                          },
                         ).marginOnly(left: 15, right: 15),
 
-
                         //输入框 - 车牌号
                         FormRequireText(
                           text: S.current.vehicle_number,
                           textColor: context.appColors.textBlack,
                           fontSize: 17,
                           fontWeight: FontWeight.w500,
-                        ).marginOnly(top: 14,bottom: 16,left: 15,right: 15),
+                        ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
 
                         // 表单
                         _buildInputLayout(
                           context,
                           "vehicle_num",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: vehicleNumController,
@@ -149,6 +144,7 @@ class VehicleInfoPage extends HookConsumerWidget {
                         _buildInputLayout(
                           context,
                           "iu_num",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.next,
                           controller: iuNumController,
@@ -165,12 +161,13 @@ class VehicleInfoPage extends HookConsumerWidget {
                           textColor: context.appColors.textBlack,
                           fontSize: 17,
                           fontWeight: FontWeight.w500,
-                        ).marginOnly(top: 14,bottom: 16,left: 15,right: 15),
+                        ).marginOnly(top: 14, bottom: 16, left: 15, right: 15),
 
                         // 表单
                         _buildInputLayout(
                           context,
                           "vehicle_info",
+                          enable: state.enableEdit,
                           textInputType: TextInputType.text,
                           textInputAction: TextInputAction.done,
                           controller: vehicleInfoController,
@@ -179,7 +176,6 @@ class VehicleInfoPage extends HookConsumerWidget {
                             vehicleInfoFocusNode.unfocus();
                           },
                         ),
-
                       ],
                     ),
                   ),
@@ -187,11 +183,48 @@ class VehicleInfoPage extends HookConsumerWidget {
 
                 //底部按钮
                 MyButton(
-                  onPressed: (){
+                  onPressed: () {
                     vehicleNumFocusNode.unfocus();
                     iuNumFocusNode.unfocus();
                     vehicleInfoFocusNode.unfocus();
 
+                    if (state.enableEdit) {
+                      String? vehicleNumber = vehicleNumController.text;
+                      String? iuNumber = iuNumController.text;
+                      String? vehicleMakeModelColour = vehicleInfoController.text;
+
+                      //校验数据
+                      final typeOfApplication = state.formContentDetail.typeOfApplication;
+                      final ownershipStatus = state.formContentDetail.ownershipStatus;
+
+                      if (Utils.isEmpty(typeOfApplication)) {
+                        ToastEngine.show("Select Type Of Application");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(ownershipStatus)) {
+                        ToastEngine.show("Select Ownership Status");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(vehicleNumber)) {
+                        ToastEngine.show("Enter vehicle number");
+                        return;
+                      }
+
+                      if (Utils.isEmpty(vehicleMakeModelColour)) {
+                        ToastEngine.show("Enter vehicle make/model/ colour");
+                        return;
+                      }
+
+                      //存入本表单数据
+                      viewModel.updateFormContentDetail((content) {
+                        content.vehicleNumber = vehicleNumber;
+                        content.vehicleMakeModelColour = vehicleMakeModelColour;
+                        content.iuNumber = iuNumber;
+                      });
+                    }
+
                     viewModel.gotoNextPage();
                   },
                   text: S.current.next,
@@ -212,20 +245,20 @@ class VehicleInfoPage extends HookConsumerWidget {
   }
 
   Widget _buildInputLayout(
-      BuildContext context,
-      String key, {
-        double marginTop = 0,
-        bool? showRightIcon = false, //是否展示右侧的布局
-        Widget? rightWidget, //右侧的布局
-        TextInputType textInputType = TextInputType.text,
-        String? errorText,
-        bool obscureText = false,
-        required TextEditingController controller,
-        required FocusNode focusNode,
-        bool enable = true,
-        TextInputAction textInputAction = TextInputAction.done,
-        Function? onSubmit,
-      }) {
+    BuildContext context,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    required TextEditingController controller,
+    required FocusNode focusNode,
+    bool enable = true,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
     return IgnoreKeyboardDismiss(
       child: MyTextField(
         key,
@@ -238,7 +271,7 @@ class VehicleInfoPage extends HookConsumerWidget {
         ),
         controller: controller,
         focusNode: focusNode,
-        margin: EdgeInsets.only(top: marginTop,left: 15,right: 15),
+        margin: EdgeInsets.only(top: marginTop, left: 15, right: 15),
         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
         showDivider: false,
         height: 44,
@@ -260,5 +293,4 @@ class VehicleInfoPage extends HookConsumerWidget {
       ),
     );
   }
-
 }

+ 31 - 8
packages/cpt_form/lib/modules/apply/vm/apply_state.dart

@@ -1,37 +1,60 @@
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/form_list_entity.dart';
+import 'package:domain/entity/form_option_entity.dart';
 import 'package:flutter/material.dart';
 
 class ApplyState {
-
-  //详情页面的索引,为了记录详情页面组的当前跳转索引,不参与状态所以不用参与Copy方法
   int detailPageIndex;
 
   //表单类型(列表的Form类型)
   String? formType;
 
+  String? estateFormId;
+
+  //该房产小区对应的此 Form 信息,从Apply 的列表item中拿过来
+  FormListEntity? formItem;
+
   //是否可编辑
   bool enableEdit;
 
-  //详情数据
-  Map<String, dynamic>? applyDetail;
+  //页面组的信息
+  Map<String, dynamic>? detailPage;
+
+  //复显的详情数据(来自网络数据)
+  FormContentEntity formContentDetail;
+
+  FormOptionEntity? formOption;
 
   ApplyState({
     this.formType,
-    this.applyDetail,
+    this.estateFormId,
+    this.formItem,
+    this.detailPage,
+    this.formOption,
+    required this.formContentDetail,
     this.enableEdit = true,
     this.detailPageIndex = 0,
   });
 
   ApplyState copyWith({
     String? formType,
+    String? estateFormId,
+    FormListEntity? formItem,
     bool? enableEdit,
-    Map<String, dynamic>? applyDetail,
+    Map<String, dynamic>? detailPage,
+    FormContentEntity? formContentDetail,
+    FormOptionEntity? formOption,
   }) {
     return ApplyState(
       formType: formType ?? this.formType,
+      estateFormId: estateFormId ?? this.estateFormId,
+      formItem: formItem ?? this.formItem,
       enableEdit: enableEdit ?? this.enableEdit,
-      applyDetail: applyDetail ?? this.applyDetail,
+      detailPage: detailPage ?? this.detailPage,
+      formContentDetail: formContentDetail ?? this.formContentDetail,
+      formOption: formOption ?? this.formOption,
+      detailPageIndex: this.detailPageIndex,
     );
   }
-
 }

+ 114 - 11
packages/cpt_form/lib/modules/apply/vm/apply_view_model.dart

@@ -1,7 +1,13 @@
 import 'dart:ui';
 
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/form_list_entity.dart';
+import 'package:domain/repository/form_repository.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/picker/date_picker_util.dart';
@@ -13,23 +19,44 @@ import 'package:widgets/picker/option_pick_util.dart';
 part 'apply_view_model.g.dart';
 
 @riverpod
-class ApplyViewModel extends _$ApplyViewModel {
+class ApplyViewModel extends _$ApplyViewModel with DioCancelableMixin {
+  late final FormRepository _formRepository;
+
   @override
   ApplyState build() {
-    return ApplyState();
+    _formRepository = ref.read(formRepositoryProvider);
+    final state = ApplyState(formContentDetail: FormContentEntity());
+    registerCancellation();
+    return state;
   }
 
   //设置具体的表单类型
-  void setFormType(String formType) {
-    final detail = FormTypes.detailPageMap[formType];
-    Log.d("applyViewModelProvider - detail:$detail");
-    state = state.copyWith(formType: formType, applyDetail: detail);
+  void setFormType(String formType, String? estateFormId, FormListEntity? formItem, bool enableEdit, FormContentEntity? formContent) {
+    final detail = FormTypes.buildDetailPageMap(enableEdit)[formType];
+    if (enableEdit) {
+      state = state.copyWith(
+        formType: formType,
+        detailPage: detail,
+        formItem: formItem,
+        enableEdit: enableEdit,
+        estateFormId: estateFormId ?? formItem?.id,
+      );
+    } else {
+      state = state.copyWith(
+        formType: formType,
+        detailPage: detail,
+        formItem: formItem,
+        enableEdit: enableEdit,
+        formContentDetail: formContent,
+        estateFormId: estateFormId ?? formItem?.id,
+      );
+    }
   }
 
   //进入下一步页面
   void gotoNextPage() {
     Log.d("applyViewModelProvider - detailPageIndex:${state.detailPageIndex}");
-    bool success = FormTypes.startDetailPageByType(state.applyDetail?['detail_pages'], state.detailPageIndex);
+    bool success = FormTypes.startDetailPageByType(state.detailPage?['detail_pages'], state.detailPageIndex);
     Log.d("applyViewModelProvider - gotoNextPage - success:$success");
     if (!success) {
       FormPage.startInstance();
@@ -44,15 +71,53 @@ class ApplyViewModel extends _$ApplyViewModel {
   }
 
   //选择一个选项
-  void pickOption() {
+  void pickOption(bool isApplicationType) async {
+    Log.d("当前的optionList:${state.formOption}");
+    if (state.formOption == null) {
+      //请求接口
+      final result = await _formRepository.fetchFormOption(typeId: state.formType, cancelToken: cancelToken);
+
+      if (result.isSuccess) {
+        state = state.copyWith(formOption: result.data);
+        _showPicker(isApplicationType);
+      } else {
+        ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+      }
+    } else {
+      _showPicker(isApplicationType);
+    }
+  }
+
+  //展示分类的PickerView
+  void _showPicker(bool isApplicationType) {
+    List<String>? list;
+    if (isApplicationType) {
+      list = state.formOption?.typeOfApplication;
+    } else {
+      list = state.formOption?.ownershipStatus;
+    }
+
+    if (list == null || list.isEmpty) return;
+
     OptionPickerUtil.showCupertinoOptionPicker(
-      items: ["选项1", "选项2", "选项3"],
+      items: list,
       initialSelectIndex: 0,
-      onPickerChanged: (_, index) {},
+      onPickerChanged: (_, index) {
+        final value = list![index];
+        if (isApplicationType) {
+          updateFormContentDetail((content) {
+            content.typeOfApplication = value;
+          });
+        } else {
+          updateFormContentDetail((content) {
+            content.ownershipStatus = value;
+          });
+        }
+      },
     );
   }
 
-  //选择一个日期,并回调出去
+  //选择一个日期,并回调出去赋值
   void pickDate(DateTime? selectedDate, void Function(DateTime) dateCallback) {
     DatePickerUtil.showCupertinoDatePicker(
       selectedDateTime: selectedDate ?? DateTime.now(),
@@ -64,4 +129,42 @@ class ApplyViewModel extends _$ApplyViewModel {
     );
   }
 
+  //选择一个时间 时分秒
+  void pickTime(DateTime? selectedDate, void Function(DateTime) dateCallback) {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedDate ?? DateTime.now(),
+      mode: CupertinoDatePickerMode.time,
+      onDateTimeChanged: (date) {
+        dateCallback.call(date);
+      },
+      title: S.current.choose_date,
+    );
+  }
+
+  /// 更新页面内容状态数据
+  void updateFormContentDetail(void Function(FormContentEntity) update) {
+    //先创建一个新对象
+    final updatedDetail = state.formContentDetail.copyWith();
+    //更新新对象的值
+    update(updatedDetail);
+    //更新State
+    state = state.copyWith(formContentDetail: updatedDetail);
+  }
+
+  /// 提交Form表单
+  void submitForm() async {
+    final result = await _formRepository.submitForm(
+      estateFormId: state.estateFormId,
+      typeId: state.formType,
+      content: state.formContentDetail,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess(S.current.successful);
+      gotoNextPage();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
 }

+ 1 - 1
packages/cpt_form/lib/modules/apply/vm/apply_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'apply_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$applyViewModelHash() => r'ea1cdebf421fe02f772e0f1896e1bf37df0b5a5c';
+String _$applyViewModelHash() => r'd79f7a3eb669265cc9d4c43850736b215051ef49';
 
 /// See also [ApplyViewModel].
 @ProviderFor(ApplyViewModel)

+ 38 - 22
packages/cpt_form/lib/modules/detail/detail_approved_fragment.dart

@@ -4,13 +4,19 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../apply/form_terms_page.dart';
+import 'form_detail_view_model.dart';
+
 class DetailApprovedFragment extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(formDetailViewModelProvider);
+
     return SizedBox(
       width: double.infinity,
       height: double.infinity,
@@ -51,7 +57,7 @@ class DetailApprovedFragment extends HookConsumerWidget {
                           text: S.current.send_on_sometime(' '),
                         ),
                         TextSpan(
-                          text: "21 Nov 2024, 03:08 PM",
+                          text: state.forDetail?.sentOn ?? "-",
                           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: context.appColors.textBlack),
                         ),
                       ],
@@ -67,7 +73,7 @@ class DetailApprovedFragment extends HookConsumerWidget {
                           text: S.current.approved_on_sometime(' '),
                         ),
                         TextSpan(
-                          text: "21 Nov 2024, 03:08 PM",
+                          text: state.forDetail?.approvedOn ?? "-",
                           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: context.appColors.textBlack),
                         ),
                       ],
@@ -83,24 +89,24 @@ class DetailApprovedFragment extends HookConsumerWidget {
                   ),
 
                   //通行卡的数据
-                  MyTextView(
-                    S.current.serial_number,
-                    marginLeft: 50,
-                    marginRight: 50,
-                    textAlign: TextAlign.center,
-                    textColor: context.appColors.textBlack,
-                    fontSize: 17,
-                    isFontRegular: true,
-                  ),
-
-                  MyTextView(
-                    "PL24087",
-                    marginTop: 16,
-                    marginBottom: 16,
-                    textColor: context.appColors.textPrimary,
-                    fontSize: 24,
-                    isFontMedium: true,
-                  ),
+                  // MyTextView(
+                  //   S.current.serial_number,
+                  //   marginLeft: 50,
+                  //   marginRight: 50,
+                  //   textAlign: TextAlign.center,
+                  //   textColor: context.appColors.textBlack,
+                  //   fontSize: 17,
+                  //   isFontRegular: true,
+                  // ),
+                  //
+                  // MyTextView(
+                  //   "PL24087",
+                  //   marginTop: 16,
+                  //   marginBottom: 16,
+                  //   textColor: context.appColors.textPrimary,
+                  //   fontSize: 24,
+                  //   isFontMedium: true,
+                  // ),
 
                   //提示 Feedback 文本
                   MyTextView(
@@ -120,7 +126,9 @@ class DetailApprovedFragment extends HookConsumerWidget {
           Row(
             children: [
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  ComponentServiceManager().mainService.startFeedbackCreatePage(context: context);
+                },
                 text: S.current.send_feedback,
                 textColor: Colors.white,
                 fontSize: 15,
@@ -130,7 +138,15 @@ class DetailApprovedFragment extends HookConsumerWidget {
               ).expanded(),
               const SizedBox(width: 10),
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  FormTermsPage.startInstance(
+                      formType: state.typeId ?? "",
+                      estateFormId: state.estateFormId,
+                      formItem: null,
+                      enableEdit: false,
+                      formContent: state.forDetail?.content,
+                  );
+                },
                 text: S.current.view_application,
                 textColor: Colors.white,
                 fontSize: 15,

+ 20 - 4
packages/cpt_form/lib/modules/detail/detail_not_approved_fragment.dart

@@ -4,13 +4,19 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/componentRouter/component_service_manager.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_button.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../apply/form_terms_page.dart';
+import 'form_detail_view_model.dart';
+
 class DetailNotApprovedFragment extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(formDetailViewModelProvider);
+
     return SizedBox(
       width: double.infinity,
       height: double.infinity,
@@ -51,7 +57,7 @@ class DetailNotApprovedFragment extends HookConsumerWidget {
                           text: S.current.send_on_sometime(' '),
                         ),
                         TextSpan(
-                          text: "21 Nov 2024, 03:08 PM",
+                          text: state.forDetail?.sentOn ?? "-",
                           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: context.appColors.textBlack),
                         ),
                       ],
@@ -67,7 +73,7 @@ class DetailNotApprovedFragment extends HookConsumerWidget {
                           text: S.current.approved_on_sometime(' '),
                         ),
                         TextSpan(
-                          text: "21 Nov 2024, 03:08 PM",
+                          text: state.forDetail?.rejectedOn ?? "-",
                           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: context.appColors.textBlack),
                         ),
                       ],
@@ -119,7 +125,9 @@ class DetailNotApprovedFragment extends HookConsumerWidget {
           Row(
             children: [
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  ComponentServiceManager().mainService.startFeedbackCreatePage(context: context);
+                },
                 text: S.current.send_feedback,
                 textColor: Colors.white,
                 fontSize: 15,
@@ -129,7 +137,15 @@ class DetailNotApprovedFragment extends HookConsumerWidget {
               ).expanded(),
               const SizedBox(width: 10),
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  FormTermsPage.startInstance(
+                      formType: state.typeId ?? "",
+                      estateFormId: state.estateFormId,
+                      formItem: null,
+                      enableEdit: false,
+                      formContent: state.forDetail?.content,
+                  );
+                },
                 text: S.current.view_application,
                 textColor: Colors.white,
                 fontSize: 15,

+ 23 - 7
packages/cpt_form/lib/modules/detail/detail_processing_fragment.dart

@@ -5,14 +5,21 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/componentRouter/component_service_manager.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';
 
+import '../apply/form_terms_page.dart';
+import '../form/form_types.dart';
+import 'form_detail_view_model.dart';
+
 class DetailProcessingFragment extends HookConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(formDetailViewModelProvider);
+
     return SizedBox(
       width: double.infinity,
       height: double.infinity,
@@ -53,12 +60,12 @@ class DetailProcessingFragment extends HookConsumerWidget {
                           text: S.current.send_on_sometime(' '),
                         ),
                         TextSpan(
-                          text: "21 Nov 2024, 03:08 PM",
+                          text: state.forDetail?.sentOn ?? "-",
                           style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, color: context.appColors.textBlack),
                         ),
                       ],
                     ),
-                  ).marginOnly(top: 12,bottom: 28),
+                  ).marginOnly(top: 12, bottom: 28),
 
                   //图片
                   const MyAssetImage(
@@ -88,7 +95,7 @@ class DetailProcessingFragment extends HookConsumerWidget {
                   Align(
                     alignment: Alignment.centerLeft, // 左对齐
                     child: MyTextView(
-                      "Access Card - Owner",
+                      FormTypes.iconMap[state.typeId]?['name'],
                       marginTop: 22,
                       marginBottom: 12,
                       marginLeft: 18,
@@ -101,7 +108,7 @@ class DetailProcessingFragment extends HookConsumerWidget {
                   Align(
                     alignment: Alignment.centerLeft, // 左对齐
                     child: MyTextView(
-                      "Damaged or faulty",
+                      state.forDetail?.content?.typeOfApplication ?? "-",
                       marginBottom: 22,
                       marginLeft: 18,
                       textColor: context.appColors.textBlack,
@@ -109,7 +116,6 @@ class DetailProcessingFragment extends HookConsumerWidget {
                       isFontMedium: true,
                     ),
                   ),
-
                 ],
               ),
             ),
@@ -117,7 +123,9 @@ class DetailProcessingFragment extends HookConsumerWidget {
           Row(
             children: [
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  ComponentServiceManager().mainService.startFeedbackCreatePage(context: context);
+                },
                 text: S.current.send_feedback,
                 textColor: Colors.white,
                 fontSize: 15,
@@ -127,7 +135,15 @@ class DetailProcessingFragment extends HookConsumerWidget {
               ).expanded(),
               const SizedBox(width: 10),
               MyButton(
-                onPressed: () {},
+                onPressed: () {
+                  FormTermsPage.startInstance(
+                    formType: state.typeId ?? "",
+                    estateFormId: state.estateFormId,
+                    formItem: null,
+                    enableEdit: false,
+                    formContent: state.forDetail?.content,
+                  );
+                },
                 text: S.current.view_application,
                 textColor: Colors.white,
                 fontSize: 15,

+ 13 - 7
packages/cpt_form/lib/modules/detail/form_detail_page.dart

@@ -17,25 +17,28 @@ import 'form_detail_view_model.dart';
 
 @RoutePage()
 class FormDetailPage extends HookConsumerWidget {
-  final String applyId;
+  final String estateFormId;
+  final String taskId;
   final String type;
 
   const FormDetailPage({
     Key? key,
-    @PathParam() required this.applyId,
+    @PathParam() required this.estateFormId,
+    @PathParam() required this.taskId,
     @PathParam() required this.type,
   }) : super(key: key);
 
   //启动当前页面
   static void startInstance({
     BuildContext? context,
-    required String applyId,
+    required String estateFormId,
+    required String taskId,
     required String type,
   }) {
     if (context != null) {
-      context.router.push(FormDetailPageRoute(applyId: applyId, type: type));
+      context.router.push(FormDetailPageRoute(estateFormId: estateFormId, taskId: taskId, type: type));
     } else {
-      appRouter.push(FormDetailPageRoute(applyId: applyId, type: type));
+      appRouter.push(FormDetailPageRoute(estateFormId: estateFormId, taskId: taskId, type: type));
     }
   }
 
@@ -46,7 +49,10 @@ class FormDetailPage extends HookConsumerWidget {
 
     useEffect(() {
       // 组件挂载时执行 - 执行接口请求
-      Future.microtask(() => viewModel.fetchFormDetail());
+      Future.microtask((){
+        viewModel.setType(type);
+        viewModel.fetchFormDetail(estateFormId, taskId);
+      });
       return () {
         // 组件卸载时执行
       };
@@ -62,7 +68,7 @@ class FormDetailPage extends HookConsumerWidget {
             state: state.loadingState,
             errorMessage: state.errorMessage,
             errorRetry: () {
-              viewModel.retryRequest();
+              viewModel.retryRequest(estateFormId, taskId);
             },
             successWidget: state.status == 0
                 ? DetailProcessingFragment()

+ 16 - 0
packages/cpt_form/lib/modules/detail/form_detail_state.dart

@@ -1,3 +1,5 @@
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/form_detail_entity.dart';
 import 'package:widgets/load_state_layout.dart';
 
 class FormDetailState{
@@ -8,23 +10,37 @@ class FormDetailState{
 
   int status;  // 0是Pending , 1是Approve , 2是Not Approve
 
+  FormDetailEntity? forDetail;
+
+  String? typeId;
+  String? estateFormId;
+
   // ===================================  Begin  ↓  ===================================
 
   FormDetailState({
     this.loadingState = LoadState.State_Loading,
     this.errorMessage,
     this.status = 0,
+    this.forDetail,
+    this.typeId,
+    this.estateFormId,
   });
 
   FormDetailState copyWith({
     LoadState? loadingState,
     String? errorMessage,
+    String? typeId,
+    String? estateFormId,
     int? status,
+    FormDetailEntity? forDetail,
   }) {
     return FormDetailState(
       errorMessage: errorMessage ?? this.errorMessage,
       loadingState: loadingState ?? this.loadingState,
       status: status ?? this.status,
+      forDetail: forDetail ?? this.forDetail,
+      typeId: typeId ?? this.typeId,
+      estateFormId: estateFormId ?? this.estateFormId,
     );
   }
 

+ 22 - 9
packages/cpt_form/lib/modules/detail/form_detail_view_model.dart

@@ -1,3 +1,5 @@
+import 'package:domain/repository/form_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:widgets/load_state_layout.dart';
 
@@ -6,26 +8,37 @@ import 'form_detail_state.dart';
 part 'form_detail_view_model.g.dart';
 
 @riverpod
-class FormDetailViewModel extends _$FormDetailViewModel {
+class FormDetailViewModel extends _$FormDetailViewModel with DioCancelableMixin {
+  late final FormRepository _formRepository;
+
   @override
   FormDetailState build() {
-    return FormDetailState();
+    _formRepository = ref.read(formRepositoryProvider);
+    final state = FormDetailState();
+    registerCancellation();
+    return state;
+  }
+
+  void setType(String type) {
+    state = state.copyWith(typeId: type);
   }
 
-  void retryRequest() {
-    fetchFormDetail();
+  void retryRequest(String? estateFormId, String? taskId) {
+    fetchFormDetail(estateFormId, taskId);
   }
 
   //获取表单的详情数据
-  void fetchFormDetail() async {
+  void fetchFormDetail(String? estateFormId, String? taskId) async {
     //显示加载数据
     state = state.copyWith(loadingState: LoadState.State_Loading);
 
-    await Future.delayed(const Duration(milliseconds: 1500));
+    final result = await _formRepository.fetchFormDetail(estateFormId: estateFormId, taskId: taskId);
 
     //根据后端返回的数据赋值状态
-    state = state.copyWith(loadingState: LoadState.State_Success, status: 2);
-
-
+    if (result.isSuccess) {
+      state = state.copyWith(loadingState: LoadState.State_Success, status: result.data?.status, forDetail: result.data, estateFormId: estateFormId);
+    } else {
+      state = state.copyWith(loadingState: LoadState.State_Error, errorMessage: result.errorMsg);
+    }
   }
 }

+ 1 - 1
packages/cpt_form/lib/modules/detail/form_detail_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'form_detail_view_model.dart';
 // **************************************************************************
 
 String _$formDetailViewModelHash() =>
-    r'ff75168453999e002ef05e85ede97021615b2181';
+    r'cb3ec02850ae818982d6358f0935b09546515ba1';
 
 /// See also [FormDetailViewModel].
 @ProviderFor(FormDetailViewModel)

+ 6 - 1
packages/cpt_form/lib/modules/form/apply/form_apply_screen.dart

@@ -43,7 +43,12 @@ class FormApplyScreen extends HookConsumerWidget {
               (context, index) {
                 return FormApplyItem(index: index, item: state.datas[index]).onTap(() {
                   //进入申请的协议页面
-                  FormTermsPage.startInstance(formType: state.datas[index]);
+                  FormTermsPage.startInstance(
+                    formType: state.datas[index].typeId!,
+                    estateFormId: null,
+                    formItem: state.datas[index],
+                    enableEdit: true,
+                  );
                 });
               },
               childCount: state.datas.length,

+ 3 - 2
packages/cpt_form/lib/modules/form/apply/form_apply_state.dart

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

+ 28 - 61
packages/cpt_form/lib/modules/form/apply/form_apply_view_model.dart

@@ -1,3 +1,6 @@
+import 'package:domain/entity/form_list_entity.dart';
+import 'package:domain/repository/form_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,7 +11,8 @@ import 'form_apply_state.dart';
 part 'form_apply_view_model.g.dart';
 
 @riverpod
-class FormApplyViewModel extends _$FormApplyViewModel {
+class FormApplyViewModel extends _$FormApplyViewModel with DioCancelableMixin {
+  late final FormRepository _formRepository;
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
@@ -19,7 +23,10 @@ class FormApplyViewModel extends _$FormApplyViewModel {
 
   @override
   FormApplyState build() {
-    return FormApplyState(datas: []);
+    _formRepository = ref.read(formRepositoryProvider);
+    final state = FormApplyState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -45,71 +52,31 @@ class FormApplyViewModel extends _$FormApplyViewModel {
     }
 
     // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
+    var result = await _formRepository.fetchFormApplyList(
+      cancelToken: cancelToken,
+    );
 
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-
-    if (list.isNotEmpty) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
+    // 处理数据
+    if (result.isSuccess) {
+      handleList(result.list);
     } else {
-      //加载更多
-      state = state.copyWith(datas: []);
-      changeLoadingState(LoadState.State_Empty, null);
+      changeLoadingState(LoadState.State_Error, result.errorMsg);
     }
 
     // 最后赋值
     _needShowPlaceholder = false;
   }
 
-// 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  // 处理数据与展示的逻辑
+  void handleList(List<FormListEntity>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据
+      state = state.copyWith(datas: list, loadingState: LoadState.State_Success);
+    } else {
+      //展示无数据的布局
+      state = state.copyWith(datas: [], loadingState: LoadState.State_Empty, errorMessage: null);
+    }
+
+    refreshController.finishRefresh();
+  }
 }

+ 1 - 1
packages/cpt_form/lib/modules/form/apply/form_apply_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'form_apply_view_model.dart';
 // **************************************************************************
 
 String _$formApplyViewModelHash() =>
-    r'1fba2b4d77c876507a8138c25ccf205d2b819f72';
+    r'6ec50f08281d0d52345741459787d25046f77be2';
 
 /// See also [FormApplyViewModel].
 @ProviderFor(FormApplyViewModel)

+ 7 - 6
packages/cpt_form/lib/modules/form/apply/item_form_apply.dart

@@ -1,6 +1,7 @@
 import 'package:cpt_form/modules/form/form_types.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/form_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
@@ -9,7 +10,7 @@ import 'package:widgets/my_text_view.dart';
 ///  设施的Active的Item
 class FormApplyItem extends StatelessWidget {
   final int index;
-  final String item;
+  final FormListEntity item;
 
   const FormApplyItem({
     required this.index,
@@ -31,14 +32,14 @@ class FormApplyItem extends StatelessWidget {
         mainAxisSize: MainAxisSize.max,
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
-          MyLoadImage(
-            FormTypes.iconMap[item]?['icon_path'],
-              width: FormTypes.iconMap[item]?['width'],
-              height: FormTypes.iconMap[item]?['height'],
+          MyAssetImage(
+            FormTypes.iconMap[item.typeId]?['icon_path'],
+              width: FormTypes.iconMap[item.typeId]?['width'],
+              height: FormTypes.iconMap[item.typeId]?['height'],
           ),
 
           MyTextView(
-            FormTypes.iconMap[item]?['name'],
+            FormTypes.iconMap[item.typeId]?['name'],
             marginLeft: 17,
             fontSize: 15,
             textColor: context.appColors.textBlack,

+ 7 - 4
packages/cpt_form/lib/modules/form/approve/form_approve_screen.dart

@@ -45,18 +45,21 @@ class FormApproveScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
               (context, index) {
-                return FormApproveItem(index: index, item: state.datas[index]).onTap((){
+                return FormApproveItem(index: index, item: state.datas[index]).onTap(() {
                   //去详情页面
-                  FormDetailPage.startInstance(context: context, applyId: "123", type: state.datas[index]);
+                  FormDetailPage.startInstance(
+                    context: context,
+                    estateFormId: state.datas[index].estateOnlineFormId ?? "",
+                    taskId: state.datas[index].id ?? "",
+                    type: state.datas[index].estateOnlineForm?.type?.id ?? "",
+                  );
                 });
               },
               childCount: state.datas.length,
             )),
-
           ],
         ),
       ).marginOnly(top: 5, bottom: 5),
     );
   }
-
 }

+ 3 - 2
packages/cpt_form/lib/modules/form/approve/form_approve_state.dart

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

+ 44 - 67
packages/cpt_form/lib/modules/form/approve/form_approve_view_model.dart

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

+ 1 - 1
packages/cpt_form/lib/modules/form/approve/form_approve_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'form_approve_view_model.dart';
 // **************************************************************************
 
 String _$formApproveViewModelHash() =>
-    r'040c903a0f3423ebccf00bf1fcaed1f0361a7ed6';
+    r'88b513f846a7e885ee951878529e54a0f63d5e67';
 
 /// See also [FormApproveViewModel].
 @ProviderFor(FormApproveViewModel)

+ 12 - 8
packages/cpt_form/lib/modules/form/approve/item_form_approve.dart

@@ -1,15 +1,17 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/form_submitted_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../form_types.dart';
 
 class FormApproveItem extends StatelessWidget {
   final int index;
-  final String item;
+  final FormSubmittedEntity item;
 
   const FormApproveItem({
     required this.index,
@@ -32,12 +34,16 @@ class FormApproveItem extends StatelessWidget {
           Row(
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              const MyAssetImage(Assets.formAccessCard, width: 38.5, height: 31),
+              MyAssetImage(
+                FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['icon_path'],
+                width: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['width'],
+                height: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['height'],
+              ),
               Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
                   MyTextView(
-                    "Access Card -Owner",
+                    FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['name'],
                     fontSize: 16,
                     maxLines: 2,
                     textColor: context.appColors.textBlack,
@@ -46,7 +52,7 @@ class FormApproveItem extends StatelessWidget {
 
                   //预订人
                   MyTextView(
-                    S.current.booked_by_someone("Wu Bing Bing"),
+                    S.current.booked_by_someone(item.account?.name ?? ""),
                     fontSize: 14,
                     marginTop: 2,
                     textColor: context.appColors.textBlack,
@@ -69,21 +75,19 @@ class FormApproveItem extends StatelessWidget {
             ],
           ),
           MyTextView(
-            S.current.send_on_sometime("04 Feb 2024 at 04:00 PM"),
+            S.current.send_on_sometime(item.sentOn ?? ""),
             fontSize: 14,
             marginTop: 10,
             textColor: context.appColors.textBlack,
             isFontRegular: true,
           ),
-
           MyTextView(
-            S.current.approved_on_sometime("04 Feb 2024 at 04:00 PM"),
+            S.current.approved_on_sometime(item.approvedOn ?? ""),
             fontSize: 14,
             marginTop: 5,
             textColor: context.appColors.textBlack,
             isFontRegular: true,
           ),
-
         ],
       ),
     );

+ 8 - 8
packages/cpt_form/lib/modules/form/form_page.dart

@@ -58,8 +58,8 @@ class FormPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.formApplyIcon,
-                      48.5,
-                      47,
+                      38,
+                      44,
                       S.current.apply,
                       tabsRouter.activeIndex == 0,
                     ).onTap(
@@ -70,8 +70,8 @@ class FormPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.formSubmitIcon,
-                      44,
-                      47,
+                      38.5,
+                      39,
                       S.current.form_submit_title,
                       tabsRouter.activeIndex == 1,
                     ).onTap(
@@ -82,8 +82,8 @@ class FormPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.formApprovedIcon,
-                      40,
-                      47,
+                      39,
+                      39,
                       S.current.approved,
                       tabsRouter.activeIndex == 2,
                     ).onTap(
@@ -94,8 +94,8 @@ class FormPage extends HookConsumerWidget {
                     _buildCategory(
                       context,
                       Assets.formNotApprovedIcon,
-                      42,
-                      46.5,
+                      38.5,
+                      39.5,
                       S.current.not_approved,
                       tabsRouter.activeIndex == 3,
                     ).onTap(

+ 191 - 189
packages/cpt_form/lib/modules/form/form_types.dart

@@ -121,195 +121,197 @@ class FormTypes {
   // ===================================  Begin  ↓  ===================================
 
   //type类型对应的详情页面组与对应的数据
-  static Map<String, Map<String, dynamic>> detailPageMap = {
-    //Access Card-Owner
-    '1': {
-      'title': S.current.access_card_owner,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.typeOfApplication,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'note_management_txt': S.current.access_card_desc,
-        'signature_txt': S.current.signature_access_card,
-      }
-    },
-    //Access Card-Tenant
-    '2': {
-      'title': S.current.access_card_tenant,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.typeOfApplication,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'attachment_txt': S.current.access_card_tenant_letter,
-        'note_management_txt': S.current.access_card_desc,
-        'signature_txt': S.current.signature_access_card,
-      }
-    },
-    //Car Park Cancellation
-    '3': {
-      'title': S.current.car_park_cancellation,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.vehicleInfo,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'note_management_txt': '${S.current.car_cancel_txt}\n\n${S.current.car_cancel_txt_1}\n${S.current.car_cancel_txt_2}',
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-    //Moving In
-    '4': {
-      'title': S.current.moving_in,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.movingDate,
-        DetailPageType.movingCompany,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'note_management_txt': S.current.moving_in_msg,
-        'signature_txt': S.current.signature_moving,
-      }
-    },
-    //Moving Out
-    '5': {
-      'title': S.current.moving_out,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.movingDate,
-        DetailPageType.movingCompany,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'note_management_txt': S.current.moving_in_msg,
-        'signature_txt': S.current.signature_moving,
-      }
-    },
-    //Overnight Parking
-    '6': {
-      'title': S.current.overnight_parking,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.guestVehicleInfo,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'note_management_txt': S.current.overnight_parking_msg,
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-    //Registration of 2nd Vehicle
-    '7': {
-      'title': S.current.registration_of_2_vehicle,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.vehicleInfo,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
-        'note_management_txt': S.current.moving_in_msg,
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-    //Renovation
-    '8': {
-      'title': S.current.renovation,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.renovationDate,
-        DetailPageType.renovationCompany,
-        DetailPageType.largeTextBox,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'large_txt': S.current.list_of_renovation_works,
-        'attachment_txt': S.current.renovation_attachments,
-        'note_management_txt': S.current.renovation_note,
-        'signature_txt': S.current.signature_renovation,
-      }
-    },
-    //Re-Registration of 1st Vehicle-Owner
-    '9': {
-      'title': S.current.re_registration_of_1_vehicle_owner,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.vehicleInfo,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
-        'note_management_txt': S.current.moving_in_msg,
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-    //Re-Registration of 1st Vehicle-Owner
-    '10': {
-      'title': S.current.re_registration_of_1_vehicle_tenant,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.vehicleInfo,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
-        'note_management_txt': S.current.moving_in_msg,
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-    //Re-Registration of Bicycles
-    '11': {
-      'title': S.current.re_registration_of_bicycle,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.typeOfApplication,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.signature,
-      ],
-      'detail_data': {
-        'attachment_txt': S.current.bicycle_desc,
-        'note_management_txt': S.current.bicycle_note,
-        'signature_txt': S.current.signature_bicycle,
-      }
-    },
-    //Vehicle Label Replacement
-    '12': {
-      'title': S.current.vehicle_label_replacement,
-      'term_url': 'https://lehuoer.com/privacy.html',
-      'detail_pages': [
-        DetailPageType.typeOfApplication,
-        DetailPageType.attachment,
-        DetailPageType.note2Management,
-        DetailPageType.payment,
-      ],
-      'detail_data': {
-        'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
-        'note_management_txt': S.current.label_replace_note,
-        'signature_txt': S.current.signature_vehicle,
-      }
-    },
-  };
+  static Map<String, Map<String, dynamic>> buildDetailPageMap(bool enableEdit) {
+    return {
+      //Access Card-Owner
+      '1': {
+        'title': S.current.access_card_owner,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.typeOfApplication,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'note_management_txt': S.current.access_card_desc,
+          'signature_txt': S.current.signature_access_card,
+        }
+      },
+      //Access Card-Tenant
+      '2': {
+        'title': S.current.access_card_tenant,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.typeOfApplication,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': S.current.access_card_tenant_letter,
+          'note_management_txt': S.current.access_card_desc,
+          'signature_txt': S.current.signature_access_card,
+        }
+      },
+      //Car Park Cancellation
+      '3': {
+        'title': S.current.car_park_cancellation,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.vehicleInfo,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'note_management_txt': '${S.current.car_cancel_txt}\n\n${S.current.car_cancel_txt_1}\n${S.current.car_cancel_txt_2}',
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+      //Moving In
+      '4': {
+        'title': S.current.moving_in,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.movingDate,
+          DetailPageType.movingCompany,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'note_management_txt': S.current.moving_in_msg,
+          'signature_txt': S.current.signature_moving,
+        }
+      },
+      //Moving Out
+      '5': {
+        'title': S.current.moving_out,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.movingDate,
+          DetailPageType.movingCompany,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'note_management_txt': S.current.moving_in_msg,
+          'signature_txt': S.current.signature_moving,
+        }
+      },
+      //Overnight Parking
+      '6': {
+        'title': S.current.overnight_parking,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.guestVehicleInfo,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'note_management_txt': S.current.overnight_parking_msg,
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+      //Registration of 2nd Vehicle
+      '7': {
+        'title': S.current.registration_of_2_vehicle,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.vehicleInfo,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
+          'note_management_txt': S.current.moving_in_msg,
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+      //Renovation
+      '8': {
+        'title': S.current.renovation,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.renovationDate,
+          DetailPageType.renovationCompany,
+          DetailPageType.largeTextBox,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'large_txt': S.current.list_of_renovation_works,
+          'attachment_txt': S.current.renovation_attachments,
+          'note_management_txt': S.current.renovation_note,
+          'signature_txt': S.current.signature_renovation,
+        }
+      },
+      //Re-Registration of 1st Vehicle-Owner
+      '9': {
+        'title': S.current.re_registration_of_1_vehicle_owner,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.vehicleInfo,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
+          'note_management_txt': S.current.moving_in_msg,
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+      //Re-Registration of 1st Vehicle-Owner
+      '10': {
+        'title': S.current.re_registration_of_1_vehicle_tenant,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.vehicleInfo,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
+          'note_management_txt': S.current.moving_in_msg,
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+      //Re-Registration of Bicycles
+      '11': {
+        'title': S.current.re_registration_of_bicycle,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.typeOfApplication,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': S.current.bicycle_desc,
+          'note_management_txt': S.current.bicycle_note,
+          'signature_txt': S.current.signature_bicycle,
+        }
+      },
+      //Vehicle Label Replacement
+      '12': {
+        'title': S.current.vehicle_label_replacement,
+        'term_url': 'https://lehuoer.com/privacy.html',
+        'detail_pages': [
+          DetailPageType.typeOfApplication,
+          DetailPageType.attachment,
+          DetailPageType.note2Management,
+          enableEdit ? DetailPageType.payment : DetailPageType.signature,
+        ],
+        'detail_data': {
+          'attachment_txt': '${S.current.label_txt}\n\n${S.current.label_txt_1}\n\n${S.current.label_txt_2}\n\n${S.current.label_txt_3}',
+          'note_management_txt': S.current.label_replace_note,
+          'signature_txt': S.current.signature_vehicle,
+        }
+      },
+    };
+  }
 
   // ===================================  Begin  ↓  ===================================
 

+ 7 - 1
packages/cpt_form/lib/modules/form/not_approve/form_not_approve_screen.dart

@@ -43,7 +43,13 @@ class FormNotApproveScreen extends HookConsumerWidget {
               (context, index) {
                 return FormNotApproveItem(index: index, item: state.datas[index]).onTap(() {
                   //去详情页面
-                  FormDetailPage.startInstance(context: context, applyId: "123", type: state.datas[index]);
+                  //去详情页面
+                  FormDetailPage.startInstance(
+                    context: context,
+                    estateFormId: state.datas[index].estateOnlineFormId ?? "",
+                    taskId: state.datas[index].id ?? "",
+                    type: state.datas[index].estateOnlineForm?.type?.id ?? "",
+                  );
                 });
               },
               childCount: state.datas.length,

+ 3 - 2
packages/cpt_form/lib/modules/form/not_approve/form_not_approve_state.dart

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

+ 48 - 70
packages/cpt_form/lib/modules/form/not_approve/form_not_approve_view_model.dart

@@ -1,3 +1,6 @@
+import 'package:domain/entity/form_submitted_entity.dart';
+import 'package:domain/repository/form_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,19 +11,23 @@ import 'form_not_approve_state.dart';
 part 'form_not_approve_view_model.g.dart';
 
 @riverpod
-class FormNotApproveViewModel extends _$FormNotApproveViewModel {
+class FormNotApproveViewModel extends _$FormNotApproveViewModel with DioCancelableMixin {
+  late final FormRepository _formRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   FormNotApproveState build() {
-    return FormNotApproveState(datas: []);
+    _formRepository = ref.read(formRepositoryProvider);
+    final state = FormNotApproveState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -53,78 +60,49 @@ class FormNotApproveViewModel extends _$FormNotApproveViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
+    // 获取列表
+    var listResult = await _formRepository.fetchFormRejectList(
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
     } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
-
-      state = state.copyWith(datas: allList);
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
     _needShowPlaceholder = false;
   }
 
-// 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  // 处理数据与展示的逻辑
+  void handleList(List<FormSubmittedEntity>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<FormSubmittedEntity>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
 }

+ 1 - 1
packages/cpt_form/lib/modules/form/not_approve/form_not_approve_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'form_not_approve_view_model.dart';
 // **************************************************************************
 
 String _$formNotApproveViewModelHash() =>
-    r'e763ac3aeaf6d5d97bf617a49cd180c672d8cf12';
+    r'3ec09df3be6c4bd9d78333952d83c831938d2111';
 
 /// See also [FormNotApproveViewModel].
 @ProviderFor(FormNotApproveViewModel)

+ 13 - 6
packages/cpt_form/lib/modules/form/not_approve/item_form_not_approve.dart

@@ -1,15 +1,18 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/form_submitted_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../form_types.dart';
+
 
 class FormNotApproveItem extends StatelessWidget {
   final int index;
-  final String item;
+  final FormSubmittedEntity item;
 
   const FormNotApproveItem({
     required this.index,
@@ -32,12 +35,16 @@ class FormNotApproveItem extends StatelessWidget {
           Row(
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              const MyAssetImage(Assets.formAccessCard, width: 38.5, height: 31),
+              MyAssetImage(
+                FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['icon_path'],
+                width: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['width'],
+                height: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['height'],
+              ),
               Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
                   MyTextView(
-                    "Access Card -Owner",
+                    FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['name'],
                     fontSize: 16,
                     maxLines: 2,
                     textColor: context.appColors.textBlack,
@@ -46,7 +53,7 @@ class FormNotApproveItem extends StatelessWidget {
 
                   //预订人
                   MyTextView(
-                    S.current.booked_by_someone("Wu Bing Bing"),
+                    S.current.booked_by_someone(item.account?.name ?? ""),
                     fontSize: 14,
                     marginTop: 2,
                     textColor: context.appColors.textBlack,
@@ -69,7 +76,7 @@ class FormNotApproveItem extends StatelessWidget {
             ],
           ),
           MyTextView(
-            S.current.send_on_sometime("04 Feb 2024 at 04:00 PM"),
+            S.current.send_on_sometime(item.sentOn ?? ""),
             fontSize: 14,
             marginTop: 10,
             textColor: context.appColors.textBlack,
@@ -77,7 +84,7 @@ class FormNotApproveItem extends StatelessWidget {
           ),
 
           MyTextView(
-            S.current.not_approved_on_sometime("04 Feb 2024 at 04:00 PM"),
+            S.current.not_approved_on_sometime(item.rejectedOn ?? ""),
             fontSize: 14,
             marginTop: 5,
             textColor: context.appColors.textBlack,

+ 7 - 1
packages/cpt_form/lib/modules/form/submit/form_submit_screen.dart

@@ -44,7 +44,13 @@ class FormSubmitScreen extends HookConsumerWidget {
               (context, index) {
                 return FormSubmitItem(index: index, item: state.datas[index]).onTap(() {
                   //去详情页面
-                  FormDetailPage.startInstance(context: context, applyId: "123", type: state.datas[index]);
+                  //去详情页面
+                  FormDetailPage.startInstance(
+                    context: context,
+                    estateFormId: state.datas[index].estateOnlineFormId ?? "",
+                    taskId: state.datas[index].id ?? "",
+                    type: state.datas[index].estateOnlineForm?.type?.id ?? "",
+                  );
                 });
               },
               childCount: state.datas.length,

+ 3 - 2
packages/cpt_form/lib/modules/form/submit/form_submit_state.dart

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

+ 48 - 70
packages/cpt_form/lib/modules/form/submit/form_submit_view_model.dart

@@ -1,3 +1,6 @@
+import 'package:domain/entity/form_submitted_entity.dart';
+import 'package:domain/repository/form_repository.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/load_state_layout.dart';
@@ -8,19 +11,23 @@ import 'form_submit_state.dart';
 part 'form_submit_view_model.g.dart';
 
 @riverpod
-class FormSubmitViewModel extends _$FormSubmitViewModel {
+class FormSubmitViewModel extends _$FormSubmitViewModel with DioCancelableMixin{
+  late final FormRepository _formRepository;
   var _curPage = 1; //请求参数当前的页面
   var _needShowPlaceholder = true; //是否展示LoadingView
 
   // Refresh 控制器
   final EasyRefreshController refreshController = EasyRefreshController(
-    controlFinishRefresh: true,  //允许刷新
-    controlFinishLoad: true,   //允许加载
+    controlFinishRefresh: true, //允许刷新
+    controlFinishLoad: true, //允许加载
   );
 
   @override
   FormSubmitState build() {
-    return FormSubmitState(datas: []);
+    _formRepository = ref.read(formRepositoryProvider);
+    final state = FormSubmitState(datas: []);
+    registerCancellation();
+    return state;
   }
 
   //刷新页面状态
@@ -53,78 +60,49 @@ class FormSubmitViewModel extends _$FormSubmitViewModel {
       changeLoadingState(LoadState.State_Loading, null);
     }
 
-    // 获取 Applied 列表
-    // var listResult = await _jobRepository.fetchJobAppliedList(
-    //   state.jobId,
-    //   state.selectedStatusId,
-    //   state.keyword,
-    //   curPage: _curPage,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // // 处理数据
-    // if (listResult.isSuccess) {
-    //   handleList(listResult.data?.rows);
-    // } else {
-    //   errorMessage = listResult.errorMsg;
-    //   changeLoadingState(LoadState.State_Error);
-    // }
+    // 获取列表
+    var listResult = await _formRepository.fetchFormSubmitList(
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
 
-
-    await Future.delayed(const Duration(milliseconds: 1500));
-
-    final List<String> list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
-
-    if (_curPage == 1) {
-      //刷新的方式
-      state = state.copyWith(datas: list);
-      refreshController.finishRefresh();
-
-      //更新展示的状态
-      changeLoadingState(LoadState.State_Success, null);
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.list);
     } else {
-      //加载更多
-      final allList = state.datas;
-      allList.addAll(list);
-      state.datas.addAll(list);
-
-      refreshController.finishLoad();
-
-      state = state.copyWith(datas: allList);
+      changeLoadingState(LoadState.State_Error, listResult.errorMsg);
     }
 
     // 最后赋值
     _needShowPlaceholder = false;
   }
 
-// 处理数据与展示的逻辑
-// void handleList(List<JobAppliedListSGRows>? list) {
-//   if (list != null && list.isNotEmpty) {
-//     //有数据,判断是刷新还是加载更多的数据
-//     if (_curPage == 1) {
-//       //刷新的方式
-//       state.datas.clear();
-//       state.datas.addAll(list);
-//       refreshController.finishRefresh();
-//
-//       //更新展示的状态
-//       changeLoadingState(LoadState.State_Success);
-//     } else {
-//       //加载更多
-//       state.datas.addAll(list);
-//       refreshController.finishLoad();
-//       update();
-//     }
-//   } else {
-//     if (_curPage == 1) {
-//       //展示无数据的布局
-//       state.datas.clear();
-//       changeLoadingState(LoadState.State_Empty);
-//       refreshController.finishRefresh();
-//     } else {
-//       //展示加载完成,没有更多数据了
-//       refreshController.finishLoad(IndicatorResult.noMore);
-//     }
-//   }
-// }
+  // 处理数据与展示的逻辑
+  void handleList(List<FormSubmittedEntity>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state = state.copyWith(datas: list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success, null);
+      } else {
+        //加载更多
+        state.datas.addAll(List<FormSubmittedEntity>.from(state.datas)..addAll(list));
+        refreshController.finishLoad();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state = state.copyWith(datas: []);
+        changeLoadingState(LoadState.State_Empty, null);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
 }

+ 1 - 1
packages/cpt_form/lib/modules/form/submit/form_submit_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'form_submit_view_model.dart';
 // **************************************************************************
 
 String _$formSubmitViewModelHash() =>
-    r'b5bfc8957a27fa130bb00ea057ca2b7d52957740';
+    r'87ef17cca1f53c2e845733c2d08b3d5e97bc7845';
 
 /// See also [FormSubmitViewModel].
 @ProviderFor(FormSubmitViewModel)

+ 12 - 5
packages/cpt_form/lib/modules/form/submit/item_form_submit.dart

@@ -1,14 +1,17 @@
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/form_submitted_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../form_types.dart';
+
 class FormSubmitItem extends StatelessWidget {
   final int index;
-  final String item;
+  final FormSubmittedEntity item;
 
   const FormSubmitItem({
     required this.index,
@@ -31,12 +34,16 @@ class FormSubmitItem extends StatelessWidget {
           Row(
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              const MyAssetImage(Assets.formAccessCard, width: 38.5, height: 31),
+              MyAssetImage(
+                FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['icon_path'],
+                width: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['width'],
+                height: FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['height'],
+              ),
               Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
                   MyTextView(
-                    "Access Card -Owner",
+                    FormTypes.iconMap[item.estateOnlineForm?.type?.id]?['name'],
                     fontSize: 16,
                     maxLines: 2,
                     textColor: context.appColors.textBlack,
@@ -45,7 +52,7 @@ class FormSubmitItem extends StatelessWidget {
 
                   //预订人
                   MyTextView(
-                    S.current.booked_by_someone("Wu Bing Bing"),
+                    S.current.booked_by_someone(item.account?.name ?? ""),
                     fontSize: 14,
                     marginTop: 2,
                     textColor: context.appColors.textBlack,
@@ -68,7 +75,7 @@ class FormSubmitItem extends StatelessWidget {
             ],
           ),
           MyTextView(
-            S.current.send_on_sometime("04 Feb 2024 at 04:00 PM"),
+            S.current.send_on_sometime(item.sentOn ?? ""),
             fontSize: 14,
             marginTop: 10,
             textColor: context.appColors.textBlack,

+ 3 - 2
packages/cpt_form/lib/router/page/form_page_router.dart

@@ -22,7 +22,8 @@ import '../../modules/apply/type_of_application_page.dart';
 import '../../modules/apply/vehicle_info_page.dart';
 import '../../modules/apply/form_terms_page.dart';
 import '../../modules/detail/form_detail_page.dart';
-
+import 'package:domain/entity/form_list_entity.dart';
+import 'package:domain/entity/form_content_entity.dart';
 part 'form_page_router.gr.dart';
 
 /*\
@@ -55,7 +56,7 @@ class FormPageRouter extends _$FormPageRouter {
         CustomRoute(page: SignaturePageRoute.page, path: RouterPath.formSignature, transitionsBuilder: applySlideTransition),
         CustomRoute(page: TypeOfApplicationPageRoute.page, path: RouterPath.formTypeOfApplication, transitionsBuilder: applySlideTransition),
         CustomRoute(page: VehicleInfoPageRoute.page, path: RouterPath.formVehicleInfo, transitionsBuilder: applySlideTransition),
-        CustomRoute(page: FormTermsPageRoute.page, path: "${RouterPath.formTerms}:type", transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FormTermsPageRoute.page, path: RouterPath.formTerms, transitionsBuilder: applySlideTransition),
         CustomRoute(page: FormDetailPageRoute.page, path: "${RouterPath.formDetail}:applyId/:type", transitionsBuilder: applySlideTransition),
       ];
 }

+ 42 - 14
packages/cpt_form/lib/router/page/form_page_router.gr.dart

@@ -37,14 +37,16 @@ abstract class _$FormPageRouter extends RootStackRouter {
       final pathParams = routeData.inheritedPathParams;
       final args = routeData.argsAs<FormDetailPageRouteArgs>(
           orElse: () => FormDetailPageRouteArgs(
-                applyId: pathParams.getString('applyId'),
+                estateFormId: pathParams.getString('estateFormId'),
+                taskId: pathParams.getString('taskId'),
                 type: pathParams.getString('type'),
               ));
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: FormDetailPage(
           key: args.key,
-          applyId: args.applyId,
+          estateFormId: args.estateFormId,
+          taskId: args.taskId,
           type: args.type,
         ),
       );
@@ -74,15 +76,16 @@ abstract class _$FormPageRouter extends RootStackRouter {
       );
     },
     FormTermsPageRoute.name: (routeData) {
-      final pathParams = routeData.inheritedPathParams;
-      final args = routeData.argsAs<FormTermsPageRouteArgs>(
-          orElse: () =>
-              FormTermsPageRouteArgs(type: pathParams.getString('type')));
+      final args = routeData.argsAs<FormTermsPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: FormTermsPage(
           key: args.key,
           type: args.type,
+          estateFormId: args.estateFormId,
+          formItem: args.formItem,
+          enableEdit: args.enableEdit,
+          formContent: args.formContent,
         ),
       );
     },
@@ -196,18 +199,21 @@ class FormApprovePageRoute extends PageRouteInfo<void> {
 class FormDetailPageRoute extends PageRouteInfo<FormDetailPageRouteArgs> {
   FormDetailPageRoute({
     Key? key,
-    required String applyId,
+    required String estateFormId,
+    required String taskId,
     required String type,
     List<PageRouteInfo>? children,
   }) : super(
           FormDetailPageRoute.name,
           args: FormDetailPageRouteArgs(
             key: key,
-            applyId: applyId,
+            estateFormId: estateFormId,
+            taskId: taskId,
             type: type,
           ),
           rawPathParams: {
-            'applyId': applyId,
+            'estateFormId': estateFormId,
+            'taskId': taskId,
             'type': type,
           },
           initialChildren: children,
@@ -222,19 +228,22 @@ class FormDetailPageRoute extends PageRouteInfo<FormDetailPageRouteArgs> {
 class FormDetailPageRouteArgs {
   const FormDetailPageRouteArgs({
     this.key,
-    required this.applyId,
+    required this.estateFormId,
+    required this.taskId,
     required this.type,
   });
 
   final Key? key;
 
-  final String applyId;
+  final String estateFormId;
+
+  final String taskId;
 
   final String type;
 
   @override
   String toString() {
-    return 'FormDetailPageRouteArgs{key: $key, applyId: $applyId, type: $type}';
+    return 'FormDetailPageRouteArgs{key: $key, estateFormId: $estateFormId, taskId: $taskId, type: $type}';
   }
 }
 
@@ -300,14 +309,21 @@ class FormTermsPageRoute extends PageRouteInfo<FormTermsPageRouteArgs> {
   FormTermsPageRoute({
     Key? key,
     required String type,
+    String? estateFormId,
+    FormListEntity? formItem,
+    required bool enableEdit,
+    FormContentEntity? formContent,
     List<PageRouteInfo>? children,
   }) : super(
           FormTermsPageRoute.name,
           args: FormTermsPageRouteArgs(
             key: key,
             type: type,
+            estateFormId: estateFormId,
+            formItem: formItem,
+            enableEdit: enableEdit,
+            formContent: formContent,
           ),
-          rawPathParams: {'type': type},
           initialChildren: children,
         );
 
@@ -321,15 +337,27 @@ class FormTermsPageRouteArgs {
   const FormTermsPageRouteArgs({
     this.key,
     required this.type,
+    this.estateFormId,
+    this.formItem,
+    required this.enableEdit,
+    this.formContent,
   });
 
   final Key? key;
 
   final String type;
 
+  final String? estateFormId;
+
+  final FormListEntity? formItem;
+
+  final bool enableEdit;
+
+  final FormContentEntity? formContent;
+
   @override
   String toString() {
-    return 'FormTermsPageRouteArgs{key: $key, type: $type}';
+    return 'FormTermsPageRouteArgs{key: $key, type: $type, estateFormId: $estateFormId, formItem: $formItem, enableEdit: $enableEdit, formContent: $formContent}';
   }
 }
 

+ 6 - 9
packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart

@@ -52,14 +52,14 @@ class FeedbackCreatePage extends HookConsumerWidget {
             children: [
               //选择类型
               FormRequireText(
-                text: S.current.full_name,
+                text: S.current.choose_category,
                 textColor: context.appColors.textBlack,
                 fontSize: 17,
               ).marginOnly(top: 14.5),
               // 选择器
               PickerContainer(
-                content: state.selectedOption ?? "",
-                hint: S.current.choose_category,
+                content: state.selectedOption?.name ?? "",
+                hint: S.current.choose_an_option,
                 margin: const EdgeInsets.only(top: 16),
                 onClick: viewModel.pickCategory,
               ),
@@ -78,7 +78,6 @@ class FeedbackCreatePage extends HookConsumerWidget {
                 marginTop: 16,
                 textInputType: TextInputType.text,
                 textInputAction: TextInputAction.next,
-                errorText: state.titleErrorText,
                 onSubmit: (formKey, value) {
                   state.formData[formKey]!['focusNode'].unfocus();
                   FocusScope.of(context).requestFocus(state.formData['desc']!['focusNode']);
@@ -86,13 +85,11 @@ class FeedbackCreatePage extends HookConsumerWidget {
               ),
 
               // DESC
-              MyTextView(
-                S.current.describe_your_feedback,
+              FormRequireText(
+                text: S.current.describe_your_feedback,
                 textColor: context.appColors.textBlack,
                 fontSize: 17,
-                marginTop: 14.5,
-                isFontMedium: true,
-              ),
+              ).marginOnly(top: 14.5),
               //大文本框
               IgnoreKeyboardDismiss(
                 child: Container(

+ 7 - 9
packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart

@@ -1,16 +1,14 @@
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/entity/id_name_entity.dart';
 import 'package:flutter/material.dart';
 
 class FeedbackCreateState {
 //表单的校验与数据
   final Map<String, Map<String, dynamic>> formData;
 
-  //表单的错误信息展示
-  String? titleErrorText;
-
   //类型选项
-  final List<String> optionList = ["条件1", "条件2", "条件3", "条件4"];
-  String? selectedOption;
+  List<IdNameEntity>? optionList;
+  IdNameEntity? selectedOption;
 
   //选择的图片
   List<String> imgList;
@@ -19,8 +17,8 @@ class FeedbackCreateState {
 
   FeedbackCreateState({
     Map<String, Map<String, dynamic>>? formData,
-    this.titleErrorText,
     required this.imgList,
+    this.optionList,
     this.selectedOption,
   }) : formData = formData ??
             {
@@ -40,14 +38,14 @@ class FeedbackCreateState {
             };
 
   FeedbackCreateState copyWith({
-    String? titleErrorText,
-    String? selectedOption,
+    List<IdNameEntity>? optionList,
+    IdNameEntity? selectedOption,
     List<String>? imgList,
   }) {
     return FeedbackCreateState(
       formData: this.formData,
-      titleErrorText: titleErrorText,
       imgList: imgList ?? this.imgList,
+      optionList: optionList ?? this.optionList,
       selectedOption: selectedOption ?? this.selectedOption,
     );
   }

+ 51 - 36
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart

@@ -1,6 +1,8 @@
 import 'package:cs_resources/generated/l10n.dart';
+import 'package:domain/repository/main_repository.dart';
 import 'package:flutter/material.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
 import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
@@ -13,27 +15,47 @@ import 'feedback_create_state.dart';
 part 'feedback_create_view_model.g.dart';
 
 @riverpod
-class FeedbackCreateViewModel extends _$FeedbackCreateViewModel {
+class FeedbackCreateViewModel extends _$FeedbackCreateViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
+
   @override
   FeedbackCreateState build() {
+    _mainRepository = ref.read(mainRepositoryProvider);
     final state = FeedbackCreateState(imgList: []);
-    initListener(state);
-    ref.onDispose(() {
-      onDispose(state);
-    });
+
+    registerCancellation();
 
     return state;
   }
 
   //选择选项
-  void pickCategory() {
+  void pickCategory() async {
     _dismissKeyboard();
+    Log.d("当前的optionList:${state.optionList}");
+    if (state.optionList == null || state.optionList!.isEmpty) {
+      //请求接口
+      final result = await _mainRepository.fetchFeedbackCategory(cancelToken: cancelToken);
+
+      if (result.isSuccess) {
+        state.optionList = result.list;
+        showCategoryPicker();
+      } else {
+        ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+      }
+    } else {
+      showCategoryPicker();
+    }
+  }
+
+  //展示分类的PickerView
+  void showCategoryPicker() {
+    if (state.optionList == null) return;
 
     OptionPickerUtil.showCupertinoOptionPicker(
-      items: state.optionList,
+      items: state.optionList!.map((e) => e.name).whereType<String>().toList(),
       initialSelectIndex: 0,
       onPickerChanged: (_, index) {
-        state = state.copyWith(selectedOption: state.optionList[index]);
+        state = state.copyWith(selectedOption: state.optionList![index]);
       },
     );
   }
@@ -46,9 +68,7 @@ class FeedbackCreateViewModel extends _$FeedbackCreateViewModel {
   }
 
   ///提交反馈
-  void submitFeedback() {
-    state = state.copyWith(titleErrorText: null);
-
+  void submitFeedback() async {
     _dismissKeyboard();
 
     final TextEditingController titleController = state.formData['title']!['controller'];
@@ -59,45 +79,40 @@ class FeedbackCreateViewModel extends _$FeedbackCreateViewModel {
 
     Log.d('当前待提交的 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
 
-    if (Utils.isEmpty(state.selectedOption)) {
+    if (state.selectedOption == null) {
       ToastEngine.show(S.current.choose_category);
       return;
     }
 
     if (Utils.isEmpty(title)) {
-      state = state.copyWith(titleErrorText: "Title cannot be empty!");
+      ToastEngine.show("Title cannot be empty!");
       return;
     }
 
+    if (Utils.isEmpty(desc)) {
+      ToastEngine.show("Enter Your FeedBack Description");
+      return;
+    }
     //执行密码登录
-    ToastEngine.show('准备执行请求 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
+    final result = await _mainRepository.postFeedback(
+      categoryId: state.selectedOption?.id,
+      title: title,
+      content: desc,
+      paths: state.imgList,
+      cancelToken: cancelToken,
+    );
 
-    //去成功页面
-    FeedbackCreateSuccessPage.startInstance();
+    if (result.isSuccess) {
+      //去成功页面
+      FeedbackCreateSuccessPage.startInstance();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
   }
 
   //选中图片
   void setImgList(List<String> list) {
+    _dismissKeyboard();
     state = state.copyWith(imgList: list);
   }
-
-  //初始化监听
-  void initListener(FeedbackCreateState initState) {
-    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
-
-    titleFocusNode.addListener(() {
-      // 获取焦点的时候清空错误文本
-      if (titleFocusNode.hasFocus) {
-        state = state.copyWith(titleErrorText: null);
-      }
-    });
-  }
-
-  //销毁资源
-  void onDispose(FeedbackCreateState initState) {
-    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
-    titleFocusNode.dispose();
-
-    Log.d("FeedbackCreateViewModel 销毁 onDispose");
-  }
 }

+ 1 - 1
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_create_view_model.dart';
 // **************************************************************************
 
 String _$feedbackCreateViewModelHash() =>
-    r'ee07ee653b4c52ef48983fa988a0043ea3b4f057';
+    r'ee4b40e8287e9137352fc27343230886bba87325';
 
 /// See also [FeedbackCreateViewModel].
 @ProviderFor(FeedbackCreateViewModel)

+ 1 - 1
packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart

@@ -55,7 +55,7 @@ class FeedbackCreateSuccessPage extends HookConsumerWidget {
 
           MyButton(
             onPressed: () {
-              MainPage.startInstance(context: context);
+              appRouter.maybePop();
             },
             text: S.current.back_home,
             textColor: Colors.white,

+ 27 - 21
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart

@@ -3,6 +3,7 @@ import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:plugin_platform/engine/image/image_nine_grid.dart';
 import 'package:router/ext/auto_router_extensions.dart';
@@ -16,14 +17,17 @@ import 'feedback_detail_view_model.dart';
 
 @RoutePage()
 class FeedbackDetailPage extends HookConsumerWidget {
-  const FeedbackDetailPage({Key? key}) : super(key: key);
+  //Feedback的Id
+  final String? id;
+
+  const FeedbackDetailPage({Key? key, required this.id}) : super(key: key);
 
   //启动当前页面
-  static void startInstance({BuildContext? context}) {
+  static void startInstance({BuildContext? context, required String? id}) {
     if (context != null) {
-      context.router.push(const FeedbackDetailPageRoute());
+      context.router.push(FeedbackDetailPageRoute(id: id));
     } else {
-      appRouter.push(const FeedbackDetailPageRoute());
+      appRouter.push(FeedbackDetailPageRoute(id: id));
     }
   }
 
@@ -32,6 +36,14 @@ class FeedbackDetailPage extends HookConsumerWidget {
     final viewModel = ref.watch(feedbackDetailViewModelProvider.notifier);
     final state = ref.watch(feedbackDetailViewModelProvider);
 
+    useEffect(() {
+      // 组件挂载时执行 - 执行接口请求
+      Future.microtask(() => viewModel.fetchFeedbackDetail(id));
+      return () {
+        // 组件卸载时执行
+      };
+    }, []);
+
     return Scaffold(
       appBar: MyAppBar.appBar(context, S.current.feedback_details, showBottomDivider: true),
       backgroundColor: context.appColors.backgroundDark,
@@ -53,13 +65,13 @@ class FeedbackDetailPage extends HookConsumerWidget {
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     MyTextView(
-                      "Exchange old houses for new ones",
+                      state.detail?.title ?? "-",
                       fontSize: 21,
                       isFontMedium: true,
                       textColor: context.appColors.textBlack,
                     ),
                     MyTextView(
-                      "18 Sep 2024 18:00  |  Security  |  In Progress",
+                      "${state.detail?.createdAt ?? ""}  |  ${state.detail?.category?.name ?? ""}  |  ${state.detail?.status == 1 ? S.current.in_progress : S.current.replied}",
                       fontSize: 12,
                       marginTop: 8,
                       isFontRegular: true,
@@ -87,9 +99,10 @@ class FeedbackDetailPage extends HookConsumerWidget {
                   ],
                 ),
                 child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     MyTextView(
-                      "Why are there no implementation rules andapplication methods for exchanging old houses for new ones in Jiang han District?",
+                      state.detail?.content ?? "",
                       fontSize: 15,
                       marginBottom: 15,
                       isFontRegular: true,
@@ -102,12 +115,7 @@ class FeedbackDetailPage extends HookConsumerWidget {
                       maxImages: 10,
                       spacing: 10,
                       aspectRatio: 108 / 80,
-                      initialImages: const [
-                        "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
-                        "https://inews.gtimg.com/om_bt/OE8piEBa-tbqn-wNvWZl8coi4AlzoUD43upEkoAnIkYL8AA/641",
-                        "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
-                        "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
-                      ],
+                      initialImages: state.detail?.resources ?? [],
                       onImagesChanged: (list) {},
                     ),
                   ],
@@ -122,6 +130,7 @@ class FeedbackDetailPage extends HookConsumerWidget {
   }
 
   Widget _buildReplyWidget(BuildContext context, WidgetRef ref) {
+    final state = ref.watch(feedbackDetailViewModelProvider);
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [
@@ -137,13 +146,13 @@ class FeedbackDetailPage extends HookConsumerWidget {
               textColor: context.appColors.textBlack,
             ).expanded(),
             MyTextView(
-              "20 sep 2024 18:00",
+              state.detail?.replies?[0].createdAt ?? "-",
               fontSize: 12,
               isFontRegular: true,
               textColor: context.appColors.textDarkGray,
             )
           ],
-        ).marginOnly(left: 12.5, right: 12.5,bottom: 14,top: 2.5),
+        ).marginOnly(left: 12.5, right: 12.5, bottom: 14, top: 2.5),
 
         //回复的内容
         Container(
@@ -163,9 +172,10 @@ class FeedbackDetailPage extends HookConsumerWidget {
             ],
           ),
           child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               MyTextView(
-                "Although the policy of exchanging old houses for new houses in Jianghan District has been released, the specific implementation details and application methods are not yet clear. According to relevant reports, Jianghan District has issued multiple measures for the development of the real estate market, including promoting the trade in policy, but the specific implementation details and application methods have not vet been announced",
+                state.detail?.replies?[0].content ?? "",
                 fontSize: 15,
                 marginBottom: 15,
                 isFontRegular: true,
@@ -178,11 +188,7 @@ class FeedbackDetailPage extends HookConsumerWidget {
                 maxImages: 10,
                 spacing: 10,
                 aspectRatio: 108 / 80,
-                initialImages: const [
-                  "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
-                  "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
-                  "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
-                ],
+                initialImages: state.detail?.replies?[0].resources ?? [],
                 onImagesChanged: (list) {},
               ),
             ],

+ 10 - 7
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart

@@ -1,18 +1,21 @@
-class FeedbackDetailState{
+import 'package:domain/entity/feedback_detail_entity.dart';
 
+class FeedbackDetailState {
   //是等待状态还是已完成状态(是否已经回复)
   bool isReplyState;
 
+  //详情数据
+  FeedbackDetailEntity? detail;
+
   FeedbackDetailState({
-     this.isReplyState = false,
+    this.isReplyState = false,
+    this.detail,
   });
 
-  FeedbackDetailState copyWith({
-    bool? isReplyState,
-  }) {
+  FeedbackDetailState copyWith({bool? isReplyState, FeedbackDetailEntity? detail}) {
     return FeedbackDetailState(
       isReplyState: isReplyState ?? this.isReplyState,
+      detail: detail ?? this.detail,
     );
   }
-
-}
+}

+ 22 - 4
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart

@@ -1,15 +1,33 @@
-
+import 'package:domain/repository/main_repository.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
 
 import 'feedback_detail_state.dart';
+
 part 'feedback_detail_view_model.g.dart';
 
 @riverpod
-class FeedbackDetailViewModel extends _$FeedbackDetailViewModel {
+class FeedbackDetailViewModel extends _$FeedbackDetailViewModel with DioCancelableMixin {
+  late final MainRepository _mainRepository;
 
   @override
-  FeedbackDetailState build(){
-    return FeedbackDetailState();
+  FeedbackDetailState build() {
+    _mainRepository = ref.read(mainRepositoryProvider);
+    final state = FeedbackDetailState();
+    registerCancellation();
+    return state;
   }
 
+  /// 获取详情数据
+  void fetchFeedbackDetail(String? id) async {
+    final result = await _mainRepository.fetchFeedbackDetail(id: id, cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      state = state.copyWith(detail: result.data, isReplyState: result.data?.replies?.isNotEmpty);
+    } else {
+      ToastEngine.show(result.errorMsg ?? "UnKnow Error");
+    }
+  }
 }

+ 1 - 1
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_detail_view_model.dart';
 // **************************************************************************
 
 String _$feedbackDetailViewModelHash() =>
-    r'c319af8c4d4805a867eb1f6481c9e6267e45cc5a';
+    r'a41644cc5725d2230d11c7a6f904b5eaa49665b6';
 
 /// See also [FeedbackDetailViewModel].
 @ProviderFor(FeedbackDetailViewModel)

+ 8 - 9
packages/cpt_main/lib/modules/feedback/history/feedback_history.dart

@@ -11,7 +11,6 @@ import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_history_view_model.dart';
 
-
 @RoutePage()
 class FeedbackHistoryScreen extends HookConsumerWidget {
   @override
@@ -44,14 +43,14 @@ class FeedbackHistoryScreen extends HookConsumerWidget {
           successSliverWidget: [
             SliverList(
                 delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
-                      FeedbackDetailPage.startInstance(context: context);
-                    });
-                  },
-                  childCount: state.datas.length,
-                ))
-            ],
+              (context, index) {
+                return FeedbackItem(index: index, item: state.datas[index]).onTap(() {
+                  FeedbackDetailPage.startInstance(context: context, id: state.datas[index].id);
+                });
+              },
+              childCount: state.datas.length,
+            ))
+          ],
         ),
       ).marginOnly(top: 5, bottom: 5),
     );

+ 3 - 2
packages/cpt_main/lib/modules/feedback/history/feedback_history_state.dart

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

+ 48 - 69
packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.dart

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

+ 1 - 1
packages/cpt_main/lib/modules/feedback/history/feedback_history_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_history_view_model.dart';
 // **************************************************************************
 
 String _$feedbackHistoryViewModelHash() =>
-    r'1be8a480c3593a25a17cd22deeefe9d707f6151a';
+    r'4ab33c4926c1af3ab217b6cc3829f3c118811476';
 
 /// See also [FeedbackHistoryViewModel].
 @ProviderFor(FeedbackHistoryViewModel)

+ 7 - 6
packages/cpt_main/lib/modules/feedback/item_feedback.dart

@@ -1,5 +1,7 @@
 import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:domain/entity/feedback_list_entity.dart';
 import 'package:flutter/material.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_load_image.dart';
@@ -7,7 +9,7 @@ import 'package:widgets/my_text_view.dart';
 
 class FeedbackItem extends StatelessWidget {
   final int index;
-  final String item;
+  final FeedbackItemEntity item;
 
   const FeedbackItem({
     required this.index,
@@ -40,17 +42,16 @@ class FeedbackItem extends StatelessWidget {
               Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
-
                   MyTextView(
-                    "Exchange old houses for new ones",
+                    item.title ?? "",
                     fontSize: 16,
                     textColor: context.appColors.textBlack,
                     isFontMedium: true,
                   ),
-
                   MyTextView(
-                    "Why are there no implementation rules and application methods for something",
+                    item.content ?? "",
                     fontSize: 14,
+                    maxLines: 2,
                     marginTop: 5,
                     textColor: context.appColors.textBlack,
                     isFontRegular: true,
@@ -62,7 +63,7 @@ class FeedbackItem extends StatelessWidget {
 
           //备注
           MyTextView(
-            "18 Sep 2024 18:00  |  Security  |  In Progress",
+            "${item.createdAt}  |  ${item.category?.name ?? ""}  |  ${item.status == 1 ? S.current.in_progress : S.current.replied}",
             fontSize: 12,
             marginTop: 10,
             textColor: context.appColors.textDarkGray,

+ 7 - 8
packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart

@@ -11,7 +11,6 @@ import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_progress_view_model.dart';
 
-
 @RoutePage()
 class FeedbackProgressScreen extends HookConsumerWidget {
   @override
@@ -44,13 +43,13 @@ class FeedbackProgressScreen extends HookConsumerWidget {
           successSliverWidget: [
             SliverList(
                 delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
-                      FeedbackDetailPage.startInstance(context: context);
-                    });
-                  },
-                  childCount: state.datas.length,
-                ))
+              (context, index) {
+                return FeedbackItem(index: index, item: state.datas[index]).onTap(() {
+                  FeedbackDetailPage.startInstance(context: context, id: state.datas[index].id);
+                });
+              },
+              childCount: state.datas.length,
+            ))
           ],
         ),
       ).marginOnly(top: 5, bottom: 5),

+ 3 - 2
packages/cpt_main/lib/modules/feedback/progress/feedback_progress_state.dart

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

+ 51 - 70
packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.dart

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

+ 1 - 1
packages/cpt_main/lib/modules/feedback/progress/feedback_progress_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'feedback_progress_view_model.dart';
 // **************************************************************************
 
 String _$feedbackProgressViewModelHash() =>
-    r'0753e433b0a575a262661e6b99030d250b69d0d0';
+    r'c3efb93d755db84c7aa75667ce2e504628759842';
 
 /// See also [FeedbackProgressViewModel].
 @ProviderFor(FeedbackProgressViewModel)

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

@@ -6,7 +6,7 @@ part of 'main_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$mainViewModelHash() => r'755642bf17f8e933622907db69f84db9cb02f40e';
+String _$mainViewModelHash() => r'e3930e02c521760d4d40336f6dd1439b36d8a000';
 
 /// See also [MainViewModel].
 @ProviderFor(MainViewModel)

+ 1 - 1
packages/cpt_main/lib/modules/me/me_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'me_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$meViewModelHash() => r'e7ffdeb5e84ad07ec6167a6249276bc25ca834fb';
+String _$meViewModelHash() => r'8244a47fa4533ff1373c03518aa3332e8c23e66b';
 
 /// See also [MeViewModel].
 @ProviderFor(MeViewModel)

+ 5 - 1
packages/cpt_main/lib/router/component/main_component_service_impl.dart

@@ -5,6 +5,8 @@ import 'package:cpt_main/modules/main/main_page.dart';
 import 'package:flutter/material.dart';
 import 'package:router/componentRouter/main_service.dart';
 
+import '../../modules/feedback/create/feedback_create_page.dart';
+
 class MainComponentServiceImpl extends MainService {
   @override
   void startMainPage({BuildContext? context}) {
@@ -12,6 +14,8 @@ class MainComponentServiceImpl extends MainService {
   }
 
   @override
-  void startSettingPage({BuildContext? context}) {}
+  void startFeedbackCreatePage({BuildContext? context}) {
+    FeedbackCreatePage.startInstance(context: context);
+  }
 }
 

+ 34 - 5
packages/cpt_main/lib/router/page/main_page_router.gr.dart

@@ -28,9 +28,13 @@ abstract class _$MainPageRouter extends RootStackRouter {
       );
     },
     FeedbackDetailPageRoute.name: (routeData) {
+      final args = routeData.argsAs<FeedbackDetailPageRouteArgs>();
       return AutoRoutePage<dynamic>(
         routeData: routeData,
-        child: const FeedbackDetailPage(),
+        child: FeedbackDetailPage(
+          key: args.key,
+          id: args.id,
+        ),
       );
     },
     FeedbackHistoryPageRoute.name: (routeData) {
@@ -186,16 +190,41 @@ class FeedbackCreateSuccessPageRoute extends PageRouteInfo<void> {
 
 /// generated route for
 /// [FeedbackDetailPage]
-class FeedbackDetailPageRoute extends PageRouteInfo<void> {
-  const FeedbackDetailPageRoute({List<PageRouteInfo>? children})
-      : super(
+class FeedbackDetailPageRoute
+    extends PageRouteInfo<FeedbackDetailPageRouteArgs> {
+  FeedbackDetailPageRoute({
+    Key? key,
+    required String? id,
+    List<PageRouteInfo>? children,
+  }) : super(
           FeedbackDetailPageRoute.name,
+          args: FeedbackDetailPageRouteArgs(
+            key: key,
+            id: id,
+          ),
           initialChildren: children,
         );
 
   static const String name = 'FeedbackDetailPageRoute';
 
-  static const PageInfo<void> page = PageInfo<void>(name);
+  static const PageInfo<FeedbackDetailPageRouteArgs> page =
+      PageInfo<FeedbackDetailPageRouteArgs>(name);
+}
+
+class FeedbackDetailPageRouteArgs {
+  const FeedbackDetailPageRouteArgs({
+    this.key,
+    required this.id,
+  });
+
+  final Key? key;
+
+  final String? id;
+
+  @override
+  String toString() {
+    return 'FeedbackDetailPageRouteArgs{key: $key, id: $id}';
+  }
 }
 
 /// generated route for

+ 55 - 0
packages/cs_domain/lib/constants/api_constants.dart

@@ -35,6 +35,18 @@ class ApiConstants {
 
   // =========================== 首页 ↓=========================================
 
+  //反馈的分类列表
+  static const apiFeedbackCategory = "/api/v1/user/feedback/category/index";
+
+  //反馈的发布
+  static const apiFeedbackPost = "/api/v1/user/feedback/index/publish";
+
+  //已发布的反馈列表
+  static const apiFeedbackList = "/api/v1/user/feedback/index";
+
+  //反馈详情
+  static const apiFeedbackDetail = "/api/v1/user/feedback/index/detail";
+
   // =========================== Profile ↓=========================================
 
   //用户Me页面详情
@@ -64,6 +76,49 @@ class ApiConstants {
   //加入房产单元
   static const apiEstateUnitJoin = "/api/v1/user/estate/unit-user/join";
 
+  // =========================== Form ↓=========================================
+
+  // 在线表单的可申请列表
+  static const apiFormList = "/api/v1/user/online-form/form/index";
+
+  // 在线表单的已批准的申请
+  static const apiFormApprovedList = "/api/v1/user/online-form/approved/index";
+
+  // 在线表单的已拒绝的申请
+  static const apiFormRejectedList = "/api/v1/user/online-form/rejected/index";
+
+  // 在线表单的已提交的申请
+  static const apiFormSubmittedList = "/api/v1/user/online-form/submitted/index";
+
+  //在线表单的选项列表
+  static const apiFormOption = "/api/v1/user/online-form/form/options";
+
+  //在线表单的提交,注意后面要拼接type
+  static const apiFormSubmit = "/api/v1/user/online-form/apply/submit/";
+
+  //在线表单的提交详情
+  static const apiFormDetail = "/api/v1/user/online-form/apply/detail";
+
+  // =========================== Facility ↓=========================================
+
+  //可用的设施列表
+  static const apiFacilityList = "/api/v1/user/facility/type/index";
+
+  //指定设施在指定日期下的可申请详情
+  static const apiFacilityDate = "/api/v1/user/facility/type/detail";
+
+  //预定指定的设施指定的日期
+  static const apiFacilityBook = "/api/v1/user/facility/booking/book";
+
+  //当前已预定的设施列表
+  static const apiFacilityActiveList = "/api/v1/user/facility/active/index";
+
+  //当前已预定的押金列表
+  static const apiFacilityDepositList = "/api/v1/user/facility/deposit/index";
+
+  //当前已预定的历史记录
+  static const apiFacilityHistoryList = "/api/v1/user/facility/history/index";
+
   // =========================== 其他 ↓=========================================
 
   //服务器时间

+ 51 - 0
packages/cs_domain/lib/entity/feedback_detail_entity.dart

@@ -0,0 +1,51 @@
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/feedback_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/feedback_detail_entity.g.dart';
+
+@JsonSerializable()
+class FeedbackDetailEntity {
+	String? id;
+	String? title;
+	String? content;
+	List<String>? resources = [];
+	int status = 0;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	IdNameEntity? category;
+	List<FeedbackDetailReplies>? replies = [];
+
+	FeedbackDetailEntity();
+
+	factory FeedbackDetailEntity.fromJson(Map<String, dynamic> json) => $FeedbackDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FeedbackDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+
+@JsonSerializable()
+class FeedbackDetailReplies {
+	String? id;
+	String? content;
+	List<String>? resources = [];
+	@JSONField(name: "created_at")
+	String? createdAt;
+	IdNameEntity? accountable;
+
+	FeedbackDetailReplies();
+
+	factory FeedbackDetailReplies.fromJson(Map<String, dynamic> json) => $FeedbackDetailRepliesFromJson(json);
+
+	Map<String, dynamic> toJson() => $FeedbackDetailRepliesToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 48 - 0
packages/cs_domain/lib/entity/feedback_list_entity.dart

@@ -0,0 +1,48 @@
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/feedback_list_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/feedback_list_entity.g.dart';
+
+@JsonSerializable()
+class FeedbackListEntity {
+	int count = 0;
+	int page = 0;
+	@JSONField(name: "count_page")
+	int countPage = 1;
+	int limit = 0;
+	List<FeedbackItemEntity>? list = [];
+
+	FeedbackListEntity();
+
+	factory FeedbackListEntity.fromJson(Map<String, dynamic> json) => $FeedbackListEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FeedbackListEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class FeedbackItemEntity {
+	String? id;
+	String? title;
+	String? content;
+	int status = 0;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	IdNameEntity? category;
+
+	FeedbackItemEntity();
+
+	factory FeedbackItemEntity.fromJson(Map<String, dynamic> json) => $FeedbackItemEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FeedbackItemEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 164 - 0
packages/cs_domain/lib/entity/form_content_entity.dart

@@ -0,0 +1,164 @@
+import 'dart:typed_data';
+
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_content_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/form_content_entity.g.dart';
+
+/*
+ * 这是Form表单的入参和出参的对象,12种类型全部整合在一个对象中
+ */
+@JsonSerializable()
+class FormContentEntity {
+  @JSONField(name: "type_of_application")
+  String? typeOfApplication;
+  @JSONField(name: "notes_to_recipient")
+  String? notesToRecipient;
+  @JSONField(name: "notes_to_management")
+  String? notesToManagement;
+  List<String>? attachments;
+  String? signature;
+  dynamic signatureByteData = null; //签名的ByteData数据
+
+  //汽车相关
+  @JSONField(name: "ownership_status")
+  String? ownershipStatus;
+  @JSONField(name: "vehicle_number")
+  String? vehicleNumber;
+  @JSONField(name: "iu_number")
+  String? iuNumber;
+  @JSONField(name: "vehicle_make_model_colour")
+  String? vehicleMakeModelColour;
+
+  //搬家相关
+  @JSONField(name: "start_date")
+  String? startDate;
+  @JSONField(name: "end_date")
+  String? endDate;
+  @JSONField(name: "time_or_arrival")
+  String? timeOrArrival;
+  @JSONField(name: "moving_company")
+  String? movingCompany;
+  @JSONField(name: "person_in_charge")
+  String? personInCharge;
+  @JSONField(name: "mobile_number")
+  String? mobileNumber;
+  @JSONField(name: "company_address")
+  String? companyAddress;
+
+  //停车过夜
+  @JSONField(name: "date_of_entry")
+  String? dateOfEntry;
+  @JSONField(name: "guest_name")
+  String? guestName;
+  @JSONField(name: "guest_mobile_number")
+  String? guestMobileNumber;
+
+  //装修
+  @JSONField(name: "renovation_start_date")
+  String? renovationStartDate;
+  @JSONField(name: "renovation_end_date")
+  String? renovationEndDate;
+  @JSONField(name: "hacking_start_date")
+  String? hackingStartDate;
+  @JSONField(name: "hacking_end_date")
+  String? hackingEndDate;
+  @JSONField(name: "renovation_company")
+  String? renovationCompany;
+  @JSONField(name: "list_of_renovation_works")
+  String? listOfRenovationWorks;
+
+
+  factory FormContentEntity.fromJson(Map<String, dynamic> json) => $FormContentEntityFromJson(json);
+
+  Map<String, dynamic> toJson() => $FormContentEntityToJson(this);
+
+  @override
+  String toString() {
+    return jsonEncode(this);
+  }
+
+  FormContentEntity({
+    this.typeOfApplication,
+    this.notesToRecipient,
+    this.notesToManagement,
+    this.attachments,
+    this.signature,
+    this.ownershipStatus,
+    this.vehicleNumber,
+    this.iuNumber,
+    this.vehicleMakeModelColour,
+    this.startDate,
+    this.endDate,
+    this.timeOrArrival,
+    this.movingCompany,
+    this.personInCharge,
+    this.mobileNumber,
+    this.companyAddress,
+    this.dateOfEntry,
+    this.guestName,
+    this.guestMobileNumber,
+    this.renovationStartDate,
+    this.renovationEndDate,
+    this.hackingStartDate,
+    this.hackingEndDate,
+    this.renovationCompany,
+    this.listOfRenovationWorks,
+  });
+
+  FormContentEntity copyWith({
+    String? typeOfApplication,
+    String? notesToRecipient,
+    String? notesToManagement,
+    List<String>? attachments,
+    String? signature,
+    String? ownershipStatus,
+    String? vehicleNumber,
+    String? iuNumber,
+    String? vehicleMakeModelColour,
+    String? startDate,
+    String? endDate,
+    String? timeOrArrival,
+    String? movingCompany,
+    String? personInCharge,
+    String? mobileNumber,
+    String? companyAddress,
+    String? dateOfEntry,
+    String? guestName,
+    String? guestMobileNumber,
+    String? renovationStartDate,
+    String? renovationEndDate,
+    String? hackingStartDate,
+    String? hackingEndDate,
+    String? renovationCompany,
+    String? listOfRenovationWorks,
+  }) {
+    return FormContentEntity(
+      typeOfApplication: typeOfApplication ?? this.typeOfApplication,
+      notesToRecipient: notesToRecipient ?? this.notesToRecipient,
+      notesToManagement: notesToManagement ?? this.notesToManagement,
+      attachments: attachments ?? this.attachments,
+      signature: signature ?? this.signature,
+      ownershipStatus: ownershipStatus ?? this.ownershipStatus,
+      vehicleNumber: vehicleNumber ?? this.vehicleNumber,
+      iuNumber: iuNumber ?? this.iuNumber,
+      vehicleMakeModelColour: vehicleMakeModelColour ?? this.vehicleMakeModelColour,
+      startDate: startDate ?? this.startDate,
+      endDate: endDate ?? this.endDate,
+      timeOrArrival: timeOrArrival ?? this.timeOrArrival,
+      movingCompany: movingCompany ?? this.movingCompany,
+      personInCharge: personInCharge ?? this.personInCharge,
+      mobileNumber: mobileNumber ?? this.mobileNumber,
+      companyAddress: companyAddress ?? this.companyAddress,
+      dateOfEntry: dateOfEntry ?? this.dateOfEntry,
+      guestName: guestName ?? this.guestName,
+      guestMobileNumber: guestMobileNumber ?? this.guestMobileNumber,
+      renovationStartDate: renovationStartDate ?? this.renovationStartDate,
+      renovationEndDate: renovationEndDate ?? this.renovationEndDate,
+      hackingStartDate: hackingStartDate ?? this.hackingStartDate,
+      hackingEndDate: hackingEndDate ?? this.hackingEndDate,
+      renovationCompany: renovationCompany ?? this.renovationCompany,
+      listOfRenovationWorks: listOfRenovationWorks ?? this.listOfRenovationWorks,
+    );
+  }
+}

+ 31 - 0
packages/cs_domain/lib/entity/form_detail_entity.dart

@@ -0,0 +1,31 @@
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/form_detail_entity.g.dart';
+
+@JsonSerializable()
+class FormDetailEntity {
+	String? id;
+	@JSONField(name: "user_id")
+	String? userId;
+	FormContentEntity? content;  //详情内容
+	int status = 0;  //0-已提交未审核,1-已审核通过,2-审核失败
+	@JSONField(name: "sent_on")
+	String? sentOn;
+	@JSONField(name: "rejected_on")
+	String? rejectedOn;
+	@JSONField(name: "approved_on")
+	String? approvedOn;
+
+	FormDetailEntity();
+
+	factory FormDetailEntity.fromJson(Map<String, dynamic> json) => $FormDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FormDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 27 - 0
packages/cs_domain/lib/entity/form_list_entity.dart

@@ -0,0 +1,27 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_list_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/form_list_entity.g.dart';
+
+@JsonSerializable()
+class FormListEntity {
+  String? id;
+  @JSONField(name: "online_form_type_id")
+  String? typeId;
+  String? icon;
+  String? name;
+  double price = 0;
+  double deposit = 0;
+  String? description;
+
+  FormListEntity();
+
+  factory FormListEntity.fromJson(Map<String, dynamic> json) => $FormListEntityFromJson(json);
+
+  Map<String, dynamic> toJson() => $FormListEntityToJson(this);
+
+  @override
+  String toString() {
+    return jsonEncode(this);
+  }
+}

+ 23 - 0
packages/cs_domain/lib/entity/form_option_entity.dart

@@ -0,0 +1,23 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_option_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/form_option_entity.g.dart';
+
+@JsonSerializable()
+class FormOptionEntity {
+  @JSONField(name: "type_of_application")
+  List<String> typeOfApplication = [];
+  @JSONField(name: "ownership_status")
+  List<String> ownershipStatus = [];
+
+  FormOptionEntity();
+
+  factory FormOptionEntity.fromJson(Map<String, dynamic> json) => $FormOptionEntityFromJson(json);
+
+  Map<String, dynamic> toJson() => $FormOptionEntityToJson(this);
+
+  @override
+  String toString() {
+    return jsonEncode(this);
+  }
+}

+ 56 - 0
packages/cs_domain/lib/entity/form_submitted_entity.dart

@@ -0,0 +1,56 @@
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/id_name_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_submitted_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/form_submitted_entity.g.dart';
+
+@JsonSerializable()
+class FormSubmittedEntity {
+	String? id;
+	@JSONField(name: "user_id")
+	String? userId;
+	@JSONField(name: "estate_online_form_id")
+	String? estateOnlineFormId;
+	FormContentEntity? content;
+	@JSONField(name: "sent_on")
+	String? sentOn;
+	@JSONField(name: "rejected_on")
+	String? rejectedOn;
+	@JSONField(name: "approved_on")
+	String? approvedOn;
+	@JSONField(name: "estate_online_form")
+	FormSubmittedEstateOnlineForm? estateOnlineForm;
+	IdNameEntity? account;
+
+	FormSubmittedEntity();
+
+	factory FormSubmittedEntity.fromJson(Map<String, dynamic> json) => $FormSubmittedEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FormSubmittedEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+
+@JsonSerializable()
+class FormSubmittedEstateOnlineForm {
+	String? id;
+	String? icon;
+	String? name;
+	IdNameEntity? type;
+
+	FormSubmittedEstateOnlineForm();
+
+	factory FormSubmittedEstateOnlineForm.fromJson(Map<String, dynamic> json) => $FormSubmittedEstateOnlineFormFromJson(json);
+
+	Map<String, dynamic> toJson() => $FormSubmittedEstateOnlineFormToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 27 - 0
packages/cs_domain/lib/entity/form_submitted_page_entity.dart

@@ -0,0 +1,27 @@
+import 'package:domain/entity/form_submitted_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/form_submitted_page_entity.g.dart';
+import 'dart:convert';
+
+export 'package:domain/generated/json/form_submitted_page_entity.g.dart';
+
+@JsonSerializable()
+class FormSubmittedPageEntity {
+	int count = 0;
+	int page =0;
+	int limit =0;
+	@JSONField(name: "count_page")
+	int countPage =0;
+	List<FormSubmittedEntity>? list = [];
+
+	FormSubmittedPageEntity();
+
+	factory FormSubmittedPageEntity.fromJson(Map<String, dynamic> json) => $FormSubmittedPageEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $FormSubmittedPageEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

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

@@ -6,6 +6,14 @@
 import 'package:flutter/material.dart' show debugPrint;
 import 'package:domain/entity/auth_login_entity.dart';
 import 'package:domain/entity/captcha_img_entity.dart';
+import 'package:domain/entity/feedback_detail_entity.dart';
+import 'package:domain/entity/feedback_list_entity.dart';
+import 'package:domain/entity/form_content_entity.dart';
+import 'package:domain/entity/form_detail_entity.dart';
+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_rent_entity.dart';
 import 'package:domain/entity/id_name_entity.dart';
 import 'package:domain/entity/newsfeed_comment_publish_entity.dart';
@@ -162,6 +170,50 @@ class JsonConvert {
       return data.map<CaptchaImgEntity>((Map<String, dynamic> e) =>
           CaptchaImgEntity.fromJson(e)).toList() as M;
     }
+    if (<FeedbackDetailEntity>[] is M) {
+      return data.map<FeedbackDetailEntity>((Map<String, dynamic> e) =>
+          FeedbackDetailEntity.fromJson(e)).toList() as M;
+    }
+    if (<FeedbackDetailReplies>[] is M) {
+      return data.map<FeedbackDetailReplies>((Map<String, dynamic> e) =>
+          FeedbackDetailReplies.fromJson(e)).toList() as M;
+    }
+    if (<FeedbackListEntity>[] is M) {
+      return data.map<FeedbackListEntity>((Map<String, dynamic> e) =>
+          FeedbackListEntity.fromJson(e)).toList() as M;
+    }
+    if (<FeedbackItemEntity>[] is M) {
+      return data.map<FeedbackItemEntity>((Map<String, dynamic> e) =>
+          FeedbackItemEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormContentEntity>[] is M) {
+      return data.map<FormContentEntity>((Map<String, dynamic> e) =>
+          FormContentEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormDetailEntity>[] is M) {
+      return data.map<FormDetailEntity>((Map<String, dynamic> e) =>
+          FormDetailEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormListEntity>[] is M) {
+      return data.map<FormListEntity>((Map<String, dynamic> e) =>
+          FormListEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormOptionEntity>[] is M) {
+      return data.map<FormOptionEntity>((Map<String, dynamic> e) =>
+          FormOptionEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormSubmittedEntity>[] is M) {
+      return data.map<FormSubmittedEntity>((Map<String, dynamic> e) =>
+          FormSubmittedEntity.fromJson(e)).toList() as M;
+    }
+    if (<FormSubmittedEstateOnlineForm>[] is M) {
+      return data.map<FormSubmittedEstateOnlineForm>((Map<String, dynamic> e) =>
+          FormSubmittedEstateOnlineForm.fromJson(e)).toList() as M;
+    }
+    if (<FormSubmittedPageEntity>[] is M) {
+      return data.map<FormSubmittedPageEntity>((Map<String, dynamic> e) =>
+          FormSubmittedPageEntity.fromJson(e)).toList() as M;
+    }
     if (<GarageSaleRentEntity>[] is M) {
       return data.map<GarageSaleRentEntity>((Map<String, dynamic> e) =>
           GarageSaleRentEntity.fromJson(e)).toList() as M;
@@ -306,6 +358,18 @@ class JsonConvertClassCollection {
   Map<String, JsonConvertFunction> convertFuncMap = {
     (AuthLoginEntity).toString(): AuthLoginEntity.fromJson,
     (CaptchaImgEntity).toString(): CaptchaImgEntity.fromJson,
+    (FeedbackDetailEntity).toString(): FeedbackDetailEntity.fromJson,
+    (FeedbackDetailReplies).toString(): FeedbackDetailReplies.fromJson,
+    (FeedbackListEntity).toString(): FeedbackListEntity.fromJson,
+    (FeedbackItemEntity).toString(): FeedbackItemEntity.fromJson,
+    (FormContentEntity).toString(): FormContentEntity.fromJson,
+    (FormDetailEntity).toString(): FormDetailEntity.fromJson,
+    (FormListEntity).toString(): FormListEntity.fromJson,
+    (FormOptionEntity).toString(): FormOptionEntity.fromJson,
+    (FormSubmittedEntity).toString(): FormSubmittedEntity.fromJson,
+    (FormSubmittedEstateOnlineForm).toString(): FormSubmittedEstateOnlineForm
+        .fromJson,
+    (FormSubmittedPageEntity).toString(): FormSubmittedPageEntity.fromJson,
     (GarageSaleRentEntity).toString(): GarageSaleRentEntity.fromJson,
     (GarageSaleRentAccount).toString(): GarageSaleRentAccount.fromJson,
     (IdNameEntity).toString(): IdNameEntity.fromJson,

+ 140 - 0
packages/cs_domain/lib/generated/json/feedback_detail_entity.g.dart

@@ -0,0 +1,140 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/feedback_detail_entity.dart';
+import 'package:domain/entity/id_name_entity.dart';
+
+
+FeedbackDetailEntity $FeedbackDetailEntityFromJson(Map<String, dynamic> json) {
+  final FeedbackDetailEntity feedbackDetailEntity = FeedbackDetailEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    feedbackDetailEntity.id = id;
+  }
+  final String? title = jsonConvert.convert<String>(json['title']);
+  if (title != null) {
+    feedbackDetailEntity.title = title;
+  }
+  final String? content = jsonConvert.convert<String>(json['content']);
+  if (content != null) {
+    feedbackDetailEntity.content = content;
+  }
+  final List<String>? resources = (json['resources'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (resources != null) {
+    feedbackDetailEntity.resources = resources;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    feedbackDetailEntity.status = status;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    feedbackDetailEntity.createdAt = createdAt;
+  }
+  final IdNameEntity? category = jsonConvert.convert<IdNameEntity>(
+      json['category']);
+  if (category != null) {
+    feedbackDetailEntity.category = category;
+  }
+  final List<FeedbackDetailReplies>? replies = (json['replies'] as List<
+      dynamic>?)
+      ?.map(
+          (e) =>
+      jsonConvert.convert<FeedbackDetailReplies>(e) as FeedbackDetailReplies)
+      .toList();
+  if (replies != null) {
+    feedbackDetailEntity.replies = replies;
+  }
+  return feedbackDetailEntity;
+}
+
+Map<String, dynamic> $FeedbackDetailEntityToJson(FeedbackDetailEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['title'] = entity.title;
+  data['content'] = entity.content;
+  data['resources'] = entity.resources;
+  data['status'] = entity.status;
+  data['created_at'] = entity.createdAt;
+  data['category'] = entity.category?.toJson();
+  data['replies'] = entity.replies?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension FeedbackDetailEntityExtension on FeedbackDetailEntity {
+  FeedbackDetailEntity copyWith({
+    String? id,
+    String? title,
+    String? content,
+    List<String>? resources,
+    int? status,
+    String? createdAt,
+    IdNameEntity? category,
+    List<FeedbackDetailReplies>? replies,
+  }) {
+    return FeedbackDetailEntity()
+      ..id = id ?? this.id
+      ..title = title ?? this.title
+      ..content = content ?? this.content
+      ..resources = resources ?? this.resources
+      ..status = status ?? this.status
+      ..createdAt = createdAt ?? this.createdAt
+      ..category = category ?? this.category
+      ..replies = replies ?? this.replies;
+  }
+}
+
+FeedbackDetailReplies $FeedbackDetailRepliesFromJson(
+    Map<String, dynamic> json) {
+  final FeedbackDetailReplies feedbackDetailReplies = FeedbackDetailReplies();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    feedbackDetailReplies.id = id;
+  }
+  final String? content = jsonConvert.convert<String>(json['content']);
+  if (content != null) {
+    feedbackDetailReplies.content = content;
+  }
+  final List<String>? resources = (json['resources'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (resources != null) {
+    feedbackDetailReplies.resources = resources;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    feedbackDetailReplies.createdAt = createdAt;
+  }
+  final IdNameEntity? accountable = jsonConvert.convert<IdNameEntity>(
+      json['accountable']);
+  if (accountable != null) {
+    feedbackDetailReplies.accountable = accountable;
+  }
+  return feedbackDetailReplies;
+}
+
+Map<String, dynamic> $FeedbackDetailRepliesToJson(
+    FeedbackDetailReplies entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['content'] = entity.content;
+  data['resources'] = entity.resources;
+  data['created_at'] = entity.createdAt;
+  data['accountable'] = entity.accountable?.toJson();
+  return data;
+}
+
+extension FeedbackDetailRepliesExtension on FeedbackDetailReplies {
+  FeedbackDetailReplies copyWith({
+    String? id,
+    String? content,
+    List<String>? resources,
+    String? createdAt,
+    IdNameEntity? accountable,
+  }) {
+    return FeedbackDetailReplies()
+      ..id = id ?? this.id
+      ..content = content ?? this.content
+      ..resources = resources ?? this.resources
+      ..createdAt = createdAt ?? this.createdAt
+      ..accountable = accountable ?? this.accountable;
+  }
+}

+ 120 - 0
packages/cs_domain/lib/generated/json/feedback_list_entity.g.dart

@@ -0,0 +1,120 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/feedback_list_entity.dart';
+import 'package:domain/entity/id_name_entity.dart';
+
+
+FeedbackListEntity $FeedbackListEntityFromJson(Map<String, dynamic> json) {
+  final FeedbackListEntity feedbackListEntity = FeedbackListEntity();
+  final int? count = jsonConvert.convert<int>(json['count']);
+  if (count != null) {
+    feedbackListEntity.count = count;
+  }
+  final int? page = jsonConvert.convert<int>(json['page']);
+  if (page != null) {
+    feedbackListEntity.page = page;
+  }
+  final int? countPage = jsonConvert.convert<int>(json['count_page']);
+  if (countPage != null) {
+    feedbackListEntity.countPage = countPage;
+  }
+  final int? limit = jsonConvert.convert<int>(json['limit']);
+  if (limit != null) {
+    feedbackListEntity.limit = limit;
+  }
+  final List<FeedbackItemEntity>? list = (json['list'] as List<dynamic>?)
+      ?.map(
+          (e) =>
+      jsonConvert.convert<FeedbackItemEntity>(e) as FeedbackItemEntity)
+      .toList();
+  if (list != null) {
+    feedbackListEntity.list = list;
+  }
+  return feedbackListEntity;
+}
+
+Map<String, dynamic> $FeedbackListEntityToJson(FeedbackListEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['count'] = entity.count;
+  data['page'] = entity.page;
+  data['count_page'] = entity.countPage;
+  data['limit'] = entity.limit;
+  data['list'] = entity.list?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension FeedbackListEntityExtension on FeedbackListEntity {
+  FeedbackListEntity copyWith({
+    int? count,
+    int? page,
+    int? countPage,
+    int? limit,
+    List<FeedbackItemEntity>? list,
+  }) {
+    return FeedbackListEntity()
+      ..count = count ?? this.count
+      ..page = page ?? this.page
+      ..countPage = countPage ?? this.countPage
+      ..limit = limit ?? this.limit
+      ..list = list ?? this.list;
+  }
+}
+
+FeedbackItemEntity $FeedbackItemEntityFromJson(Map<String, dynamic> json) {
+  final FeedbackItemEntity feedbackItemEntity = FeedbackItemEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    feedbackItemEntity.id = id;
+  }
+  final String? title = jsonConvert.convert<String>(json['title']);
+  if (title != null) {
+    feedbackItemEntity.title = title;
+  }
+  final String? content = jsonConvert.convert<String>(json['content']);
+  if (content != null) {
+    feedbackItemEntity.content = content;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    feedbackItemEntity.status = status;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    feedbackItemEntity.createdAt = createdAt;
+  }
+  final IdNameEntity? category = jsonConvert.convert<IdNameEntity>(
+      json['category']);
+  if (category != null) {
+    feedbackItemEntity.category = category;
+  }
+  return feedbackItemEntity;
+}
+
+Map<String, dynamic> $FeedbackItemEntityToJson(FeedbackItemEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['title'] = entity.title;
+  data['content'] = entity.content;
+  data['status'] = entity.status;
+  data['created_at'] = entity.createdAt;
+  data['category'] = entity.category?.toJson();
+  return data;
+}
+
+extension FeedbackItemEntityExtension on FeedbackItemEntity {
+  FeedbackItemEntity copyWith({
+    String? id,
+    String? title,
+    String? content,
+    int? status,
+    String? createdAt,
+    IdNameEntity? category,
+  }) {
+    return FeedbackItemEntity()
+      ..id = id ?? this.id
+      ..title = title ?? this.title
+      ..content = content ?? this.content
+      ..status = status ?? this.status
+      ..createdAt = createdAt ?? this.createdAt
+      ..category = category ?? this.category;
+  }
+}

+ 227 - 0
packages/cs_domain/lib/generated/json/form_content_entity.g.dart

@@ -0,0 +1,227 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_content_entity.dart';
+import 'dart:typed_data';
+
+
+FormContentEntity $FormContentEntityFromJson(Map<String, dynamic> json) {
+  final FormContentEntity formContentEntity = FormContentEntity();
+  final String? typeOfApplication = jsonConvert.convert<String>(
+      json['type_of_application']);
+  if (typeOfApplication != null) {
+    formContentEntity.typeOfApplication = typeOfApplication;
+  }
+  final String? notesToRecipient = jsonConvert.convert<String>(
+      json['notes_to_recipient']);
+  if (notesToRecipient != null) {
+    formContentEntity.notesToRecipient = notesToRecipient;
+  }
+  final String? notesToManagement = jsonConvert.convert<String>(
+      json['notes_to_management']);
+  if (notesToManagement != null) {
+    formContentEntity.notesToManagement = notesToManagement;
+  }
+  final List<String>? attachments = (json['attachments'] as List<dynamic>?)
+      ?.map(
+          (e) => jsonConvert.convert<String>(e) as String)
+      .toList();
+  if (attachments != null) {
+    formContentEntity.attachments = attachments;
+  }
+  final String? signature = jsonConvert.convert<String>(json['signature']);
+  if (signature != null) {
+    formContentEntity.signature = signature;
+  }
+  final dynamic signatureByteData = json['signatureByteData'];
+  if (signatureByteData != null) {
+    formContentEntity.signatureByteData = signatureByteData;
+  }
+  final String? ownershipStatus = jsonConvert.convert<String>(
+      json['ownership_status']);
+  if (ownershipStatus != null) {
+    formContentEntity.ownershipStatus = ownershipStatus;
+  }
+  final String? vehicleNumber = jsonConvert.convert<String>(
+      json['vehicle_number']);
+  if (vehicleNumber != null) {
+    formContentEntity.vehicleNumber = vehicleNumber;
+  }
+  final String? iuNumber = jsonConvert.convert<String>(json['iu_number']);
+  if (iuNumber != null) {
+    formContentEntity.iuNumber = iuNumber;
+  }
+  final String? vehicleMakeModelColour = jsonConvert.convert<String>(
+      json['vehicle_make_model_colour']);
+  if (vehicleMakeModelColour != null) {
+    formContentEntity.vehicleMakeModelColour = vehicleMakeModelColour;
+  }
+  final String? startDate = jsonConvert.convert<String>(json['start_date']);
+  if (startDate != null) {
+    formContentEntity.startDate = startDate;
+  }
+  final String? endDate = jsonConvert.convert<String>(json['end_date']);
+  if (endDate != null) {
+    formContentEntity.endDate = endDate;
+  }
+  final String? timeOrArrival = jsonConvert.convert<String>(
+      json['time_or_arrival']);
+  if (timeOrArrival != null) {
+    formContentEntity.timeOrArrival = timeOrArrival;
+  }
+  final String? movingCompany = jsonConvert.convert<String>(
+      json['moving_company']);
+  if (movingCompany != null) {
+    formContentEntity.movingCompany = movingCompany;
+  }
+  final String? personInCharge = jsonConvert.convert<String>(
+      json['person_in_charge']);
+  if (personInCharge != null) {
+    formContentEntity.personInCharge = personInCharge;
+  }
+  final String? mobileNumber = jsonConvert.convert<String>(
+      json['mobile_number']);
+  if (mobileNumber != null) {
+    formContentEntity.mobileNumber = mobileNumber;
+  }
+  final String? companyAddress = jsonConvert.convert<String>(
+      json['company_address']);
+  if (companyAddress != null) {
+    formContentEntity.companyAddress = companyAddress;
+  }
+  final String? dateOfEntry = jsonConvert.convert<String>(
+      json['date_of_entry']);
+  if (dateOfEntry != null) {
+    formContentEntity.dateOfEntry = dateOfEntry;
+  }
+  final String? guestName = jsonConvert.convert<String>(json['guest_name']);
+  if (guestName != null) {
+    formContentEntity.guestName = guestName;
+  }
+  final String? guestMobileNumber = jsonConvert.convert<String>(
+      json['guest_mobile_number']);
+  if (guestMobileNumber != null) {
+    formContentEntity.guestMobileNumber = guestMobileNumber;
+  }
+  final String? renovationStartDate = jsonConvert.convert<String>(
+      json['renovation_start_date']);
+  if (renovationStartDate != null) {
+    formContentEntity.renovationStartDate = renovationStartDate;
+  }
+  final String? renovationEndDate = jsonConvert.convert<String>(
+      json['renovation_end_date']);
+  if (renovationEndDate != null) {
+    formContentEntity.renovationEndDate = renovationEndDate;
+  }
+  final String? hackingStartDate = jsonConvert.convert<String>(
+      json['hacking_start_date']);
+  if (hackingStartDate != null) {
+    formContentEntity.hackingStartDate = hackingStartDate;
+  }
+  final String? hackingEndDate = jsonConvert.convert<String>(
+      json['hacking_end_date']);
+  if (hackingEndDate != null) {
+    formContentEntity.hackingEndDate = hackingEndDate;
+  }
+  final String? renovationCompany = jsonConvert.convert<String>(
+      json['renovation_company']);
+  if (renovationCompany != null) {
+    formContentEntity.renovationCompany = renovationCompany;
+  }
+  final String? listOfRenovationWorks = jsonConvert.convert<String>(
+      json['list_of_renovation_works']);
+  if (listOfRenovationWorks != null) {
+    formContentEntity.listOfRenovationWorks = listOfRenovationWorks;
+  }
+  return formContentEntity;
+}
+
+Map<String, dynamic> $FormContentEntityToJson(FormContentEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['type_of_application'] = entity.typeOfApplication;
+  data['notes_to_recipient'] = entity.notesToRecipient;
+  data['notes_to_management'] = entity.notesToManagement;
+  data['attachments'] = entity.attachments;
+  data['signature'] = entity.signature;
+  data['signatureByteData'] = entity.signatureByteData;
+  data['ownership_status'] = entity.ownershipStatus;
+  data['vehicle_number'] = entity.vehicleNumber;
+  data['iu_number'] = entity.iuNumber;
+  data['vehicle_make_model_colour'] = entity.vehicleMakeModelColour;
+  data['start_date'] = entity.startDate;
+  data['end_date'] = entity.endDate;
+  data['time_or_arrival'] = entity.timeOrArrival;
+  data['moving_company'] = entity.movingCompany;
+  data['person_in_charge'] = entity.personInCharge;
+  data['mobile_number'] = entity.mobileNumber;
+  data['company_address'] = entity.companyAddress;
+  data['date_of_entry'] = entity.dateOfEntry;
+  data['guest_name'] = entity.guestName;
+  data['guest_mobile_number'] = entity.guestMobileNumber;
+  data['renovation_start_date'] = entity.renovationStartDate;
+  data['renovation_end_date'] = entity.renovationEndDate;
+  data['hacking_start_date'] = entity.hackingStartDate;
+  data['hacking_end_date'] = entity.hackingEndDate;
+  data['renovation_company'] = entity.renovationCompany;
+  data['list_of_renovation_works'] = entity.listOfRenovationWorks;
+  return data;
+}
+
+extension FormContentEntityExtension on FormContentEntity {
+  FormContentEntity copyWith({
+    String? typeOfApplication,
+    String? notesToRecipient,
+    String? notesToManagement,
+    List<String>? attachments,
+    String? signature,
+    dynamic signatureByteData,
+    String? ownershipStatus,
+    String? vehicleNumber,
+    String? iuNumber,
+    String? vehicleMakeModelColour,
+    String? startDate,
+    String? endDate,
+    String? timeOrArrival,
+    String? movingCompany,
+    String? personInCharge,
+    String? mobileNumber,
+    String? companyAddress,
+    String? dateOfEntry,
+    String? guestName,
+    String? guestMobileNumber,
+    String? renovationStartDate,
+    String? renovationEndDate,
+    String? hackingStartDate,
+    String? hackingEndDate,
+    String? renovationCompany,
+    String? listOfRenovationWorks,
+  }) {
+    return FormContentEntity()
+      ..typeOfApplication = typeOfApplication ?? this.typeOfApplication
+      ..notesToRecipient = notesToRecipient ?? this.notesToRecipient
+      ..notesToManagement = notesToManagement ?? this.notesToManagement
+      ..attachments = attachments ?? this.attachments
+      ..signature = signature ?? this.signature
+      ..signatureByteData = signatureByteData ?? this.signatureByteData
+      ..ownershipStatus = ownershipStatus ?? this.ownershipStatus
+      ..vehicleNumber = vehicleNumber ?? this.vehicleNumber
+      ..iuNumber = iuNumber ?? this.iuNumber
+      ..vehicleMakeModelColour = vehicleMakeModelColour ??
+          this.vehicleMakeModelColour
+      ..startDate = startDate ?? this.startDate
+      ..endDate = endDate ?? this.endDate
+      ..timeOrArrival = timeOrArrival ?? this.timeOrArrival
+      ..movingCompany = movingCompany ?? this.movingCompany
+      ..personInCharge = personInCharge ?? this.personInCharge
+      ..mobileNumber = mobileNumber ?? this.mobileNumber
+      ..companyAddress = companyAddress ?? this.companyAddress
+      ..dateOfEntry = dateOfEntry ?? this.dateOfEntry
+      ..guestName = guestName ?? this.guestName
+      ..guestMobileNumber = guestMobileNumber ?? this.guestMobileNumber
+      ..renovationStartDate = renovationStartDate ?? this.renovationStartDate
+      ..renovationEndDate = renovationEndDate ?? this.renovationEndDate
+      ..hackingStartDate = hackingStartDate ?? this.hackingStartDate
+      ..hackingEndDate = hackingEndDate ?? this.hackingEndDate
+      ..renovationCompany = renovationCompany ?? this.renovationCompany
+      ..listOfRenovationWorks = listOfRenovationWorks ??
+          this.listOfRenovationWorks;
+  }
+}

+ 71 - 0
packages/cs_domain/lib/generated/json/form_detail_entity.g.dart

@@ -0,0 +1,71 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_detail_entity.dart';
+import 'package:domain/entity/form_content_entity.dart';
+
+
+FormDetailEntity $FormDetailEntityFromJson(Map<String, dynamic> json) {
+  final FormDetailEntity formDetailEntity = FormDetailEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    formDetailEntity.id = id;
+  }
+  final String? userId = jsonConvert.convert<String>(json['user_id']);
+  if (userId != null) {
+    formDetailEntity.userId = userId;
+  }
+  final FormContentEntity? content = jsonConvert.convert<FormContentEntity>(
+      json['content']);
+  if (content != null) {
+    formDetailEntity.content = content;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    formDetailEntity.status = status;
+  }
+  final String? sentOn = jsonConvert.convert<String>(json['sent_on']);
+  if (sentOn != null) {
+    formDetailEntity.sentOn = sentOn;
+  }
+  final String? rejectedOn = jsonConvert.convert<String>(json['rejected_on']);
+  if (rejectedOn != null) {
+    formDetailEntity.rejectedOn = rejectedOn;
+  }
+  final String? approvedOn = jsonConvert.convert<String>(json['approved_on']);
+  if (approvedOn != null) {
+    formDetailEntity.approvedOn = approvedOn;
+  }
+  return formDetailEntity;
+}
+
+Map<String, dynamic> $FormDetailEntityToJson(FormDetailEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['user_id'] = entity.userId;
+  data['content'] = entity.content?.toJson();
+  data['status'] = entity.status;
+  data['sent_on'] = entity.sentOn;
+  data['rejected_on'] = entity.rejectedOn;
+  data['approved_on'] = entity.approvedOn;
+  return data;
+}
+
+extension FormDetailEntityExtension on FormDetailEntity {
+  FormDetailEntity copyWith({
+    String? id,
+    String? userId,
+    FormContentEntity? content,
+    int? status,
+    String? sentOn,
+    String? rejectedOn,
+    String? approvedOn,
+  }) {
+    return FormDetailEntity()
+      ..id = id ?? this.id
+      ..userId = userId ?? this.userId
+      ..content = content ?? this.content
+      ..status = status ?? this.status
+      ..sentOn = sentOn ?? this.sentOn
+      ..rejectedOn = rejectedOn ?? this.rejectedOn
+      ..approvedOn = approvedOn ?? this.approvedOn;
+  }
+}

+ 69 - 0
packages/cs_domain/lib/generated/json/form_list_entity.g.dart

@@ -0,0 +1,69 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_list_entity.dart';
+
+FormListEntity $FormListEntityFromJson(Map<String, dynamic> json) {
+  final FormListEntity formListEntity = FormListEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    formListEntity.id = id;
+  }
+  final String? typeId = jsonConvert.convert<String>(
+      json['online_form_type_id']);
+  if (typeId != null) {
+    formListEntity.typeId = typeId;
+  }
+  final String? icon = jsonConvert.convert<String>(json['icon']);
+  if (icon != null) {
+    formListEntity.icon = icon;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    formListEntity.name = name;
+  }
+  final double? price = jsonConvert.convert<double>(json['price']);
+  if (price != null) {
+    formListEntity.price = price;
+  }
+  final double? deposit = jsonConvert.convert<double>(json['deposit']);
+  if (deposit != null) {
+    formListEntity.deposit = deposit;
+  }
+  final String? description = jsonConvert.convert<String>(json['description']);
+  if (description != null) {
+    formListEntity.description = description;
+  }
+  return formListEntity;
+}
+
+Map<String, dynamic> $FormListEntityToJson(FormListEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['online_form_type_id'] = entity.typeId;
+  data['icon'] = entity.icon;
+  data['name'] = entity.name;
+  data['price'] = entity.price;
+  data['deposit'] = entity.deposit;
+  data['description'] = entity.description;
+  return data;
+}
+
+extension FormListEntityExtension on FormListEntity {
+  FormListEntity copyWith({
+    String? id,
+    String? typeId,
+    String? icon,
+    String? name,
+    double? price,
+    double? deposit,
+    String? description,
+  }) {
+    return FormListEntity()
+      ..id = id ?? this.id
+      ..typeId = typeId ?? this.typeId
+      ..icon = icon ?? this.icon
+      ..name = name ?? this.name
+      ..price = price ?? this.price
+      ..deposit = deposit ?? this.deposit
+      ..description = description ?? this.description;
+  }
+}

+ 37 - 0
packages/cs_domain/lib/generated/json/form_option_entity.g.dart

@@ -0,0 +1,37 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_option_entity.dart';
+
+FormOptionEntity $FormOptionEntityFromJson(Map<String, dynamic> json) {
+  final FormOptionEntity formOptionEntity = FormOptionEntity();
+  final List<String>? typeOfApplication = (json['type_of_application'] as List<
+      dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (typeOfApplication != null) {
+    formOptionEntity.typeOfApplication = typeOfApplication;
+  }
+  final List<String>? ownershipStatus = (json['ownership_status'] as List<
+      dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (ownershipStatus != null) {
+    formOptionEntity.ownershipStatus = ownershipStatus;
+  }
+  return formOptionEntity;
+}
+
+Map<String, dynamic> $FormOptionEntityToJson(FormOptionEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['type_of_application'] = entity.typeOfApplication;
+  data['ownership_status'] = entity.ownershipStatus;
+  return data;
+}
+
+extension FormOptionEntityExtension on FormOptionEntity {
+  FormOptionEntity copyWith({
+    List<String>? typeOfApplication,
+    List<String>? ownershipStatus,
+  }) {
+    return FormOptionEntity()
+      ..typeOfApplication = typeOfApplication ?? this.typeOfApplication
+      ..ownershipStatus = ownershipStatus ?? this.ownershipStatus;
+  }
+}

+ 137 - 0
packages/cs_domain/lib/generated/json/form_submitted_entity.g.dart

@@ -0,0 +1,137 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_submitted_entity.dart';
+import 'package:domain/entity/form_content_entity.dart';
+
+import 'package:domain/entity/id_name_entity.dart';
+
+
+FormSubmittedEntity $FormSubmittedEntityFromJson(Map<String, dynamic> json) {
+  final FormSubmittedEntity formSubmittedEntity = FormSubmittedEntity();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    formSubmittedEntity.id = id;
+  }
+  final String? userId = jsonConvert.convert<String>(json['user_id']);
+  if (userId != null) {
+    formSubmittedEntity.userId = userId;
+  }
+  final String? estateOnlineFormId = jsonConvert.convert<String>(
+      json['estate_online_form_id']);
+  if (estateOnlineFormId != null) {
+    formSubmittedEntity.estateOnlineFormId = estateOnlineFormId;
+  }
+  final FormContentEntity? content = jsonConvert.convert<FormContentEntity>(
+      json['content']);
+  if (content != null) {
+    formSubmittedEntity.content = content;
+  }
+  final String? sentOn = jsonConvert.convert<String>(json['sent_on']);
+  if (sentOn != null) {
+    formSubmittedEntity.sentOn = sentOn;
+  }
+  final String? rejectedOn = jsonConvert.convert<String>(json['rejected_on']);
+  if (rejectedOn != null) {
+    formSubmittedEntity.rejectedOn = rejectedOn;
+  }
+  final String? approvedOn = jsonConvert.convert<String>(json['approved_on']);
+  if (approvedOn != null) {
+    formSubmittedEntity.approvedOn = approvedOn;
+  }
+  final FormSubmittedEstateOnlineForm? estateOnlineForm = jsonConvert.convert<
+      FormSubmittedEstateOnlineForm>(json['estate_online_form']);
+  if (estateOnlineForm != null) {
+    formSubmittedEntity.estateOnlineForm = estateOnlineForm;
+  }
+  final IdNameEntity? account = jsonConvert.convert<IdNameEntity>(
+      json['account']);
+  if (account != null) {
+    formSubmittedEntity.account = account;
+  }
+  return formSubmittedEntity;
+}
+
+Map<String, dynamic> $FormSubmittedEntityToJson(FormSubmittedEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['user_id'] = entity.userId;
+  data['estate_online_form_id'] = entity.estateOnlineFormId;
+  data['content'] = entity.content?.toJson();
+  data['sent_on'] = entity.sentOn;
+  data['rejected_on'] = entity.rejectedOn;
+  data['approved_on'] = entity.approvedOn;
+  data['estate_online_form'] = entity.estateOnlineForm?.toJson();
+  data['account'] = entity.account?.toJson();
+  return data;
+}
+
+extension FormSubmittedEntityExtension on FormSubmittedEntity {
+  FormSubmittedEntity copyWith({
+    String? id,
+    String? userId,
+    String? estateOnlineFormId,
+    FormContentEntity? content,
+    String? sentOn,
+    String? rejectedOn,
+    String? approvedOn,
+    FormSubmittedEstateOnlineForm? estateOnlineForm,
+    IdNameEntity? account,
+  }) {
+    return FormSubmittedEntity()
+      ..id = id ?? this.id
+      ..userId = userId ?? this.userId
+      ..estateOnlineFormId = estateOnlineFormId ?? this.estateOnlineFormId
+      ..content = content ?? this.content
+      ..sentOn = sentOn ?? this.sentOn
+      ..rejectedOn = rejectedOn ?? this.rejectedOn
+      ..approvedOn = approvedOn ?? this.approvedOn
+      ..estateOnlineForm = estateOnlineForm ?? this.estateOnlineForm
+      ..account = account ?? this.account;
+  }
+}
+
+FormSubmittedEstateOnlineForm $FormSubmittedEstateOnlineFormFromJson(
+    Map<String, dynamic> json) {
+  final FormSubmittedEstateOnlineForm formSubmittedEstateOnlineForm = FormSubmittedEstateOnlineForm();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    formSubmittedEstateOnlineForm.id = id;
+  }
+  final String? icon = jsonConvert.convert<String>(json['icon']);
+  if (icon != null) {
+    formSubmittedEstateOnlineForm.icon = icon;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    formSubmittedEstateOnlineForm.name = name;
+  }
+  final IdNameEntity? type = jsonConvert.convert<IdNameEntity>(json['type']);
+  if (type != null) {
+    formSubmittedEstateOnlineForm.type = type;
+  }
+  return formSubmittedEstateOnlineForm;
+}
+
+Map<String, dynamic> $FormSubmittedEstateOnlineFormToJson(
+    FormSubmittedEstateOnlineForm entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['icon'] = entity.icon;
+  data['name'] = entity.name;
+  data['type'] = entity.type?.toJson();
+  return data;
+}
+
+extension FormSubmittedEstateOnlineFormExtension on FormSubmittedEstateOnlineForm {
+  FormSubmittedEstateOnlineForm copyWith({
+    String? id,
+    String? icon,
+    String? name,
+    IdNameEntity? type,
+  }) {
+    return FormSubmittedEstateOnlineForm()
+      ..id = id ?? this.id
+      ..icon = icon ?? this.icon
+      ..name = name ?? this.name
+      ..type = type ?? this.type;
+  }
+}

+ 62 - 0
packages/cs_domain/lib/generated/json/form_submitted_page_entity.g.dart

@@ -0,0 +1,62 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/form_submitted_page_entity.dart';
+import 'package:domain/entity/form_submitted_entity.dart';
+
+
+FormSubmittedPageEntity $FormSubmittedPageEntityFromJson(
+    Map<String, dynamic> json) {
+  final FormSubmittedPageEntity formSubmittedPageEntity = FormSubmittedPageEntity();
+  final int? count = jsonConvert.convert<int>(json['count']);
+  if (count != null) {
+    formSubmittedPageEntity.count = count;
+  }
+  final int? page = jsonConvert.convert<int>(json['page']);
+  if (page != null) {
+    formSubmittedPageEntity.page = page;
+  }
+  final int? limit = jsonConvert.convert<int>(json['limit']);
+  if (limit != null) {
+    formSubmittedPageEntity.limit = limit;
+  }
+  final int? countPage = jsonConvert.convert<int>(json['count_page']);
+  if (countPage != null) {
+    formSubmittedPageEntity.countPage = countPage;
+  }
+  final List<FormSubmittedEntity>? list = (json['list'] as List<dynamic>?)
+      ?.map(
+          (e) =>
+      jsonConvert.convert<FormSubmittedEntity>(e) as FormSubmittedEntity)
+      .toList();
+  if (list != null) {
+    formSubmittedPageEntity.list = list;
+  }
+  return formSubmittedPageEntity;
+}
+
+Map<String, dynamic> $FormSubmittedPageEntityToJson(
+    FormSubmittedPageEntity 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 FormSubmittedPageEntityExtension on FormSubmittedPageEntity {
+  FormSubmittedPageEntity copyWith({
+    int? count,
+    int? page,
+    int? limit,
+    int? countPage,
+    List<FormSubmittedEntity>? list,
+  }) {
+    return FormSubmittedPageEntity()
+      ..count = count ?? this.count
+      ..page = page ?? this.page
+      ..limit = limit ?? this.limit
+      ..countPage = countPage ?? this.countPage
+      ..list = list ?? this.list;
+  }
+}

+ 68 - 0
packages/cs_domain/lib/repository/facility_repository.dart

@@ -0,0 +1,68 @@
+import 'dart:typed_data';
+
+import 'package:domain/entity/feedback_detail_entity.dart';
+import 'package:domain/entity/form_option_entity.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import '../constants/api_constants.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+import '../entity/form_content_entity.dart';
+import '../entity/form_detail_entity.dart';
+import '../entity/form_list_entity.dart';
+import '../entity/form_submitted_page_entity.dart';
+import '../entity/id_name_entity.dart';
+
+part 'facility_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+FacilityRepository facilityRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return FacilityRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 设施的数据仓库
+ */
+class FacilityRepository {
+  DioEngine dioEngine;
+
+  FacilityRepository({required this.dioEngine});
+
+
+  Future<HttpResult<IdNameEntity>> fetchFormApplyList({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormList,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final jsonList = result.getListJson();
+
+      //获取List数据 需要转换一次
+      var list = jsonList
+          ?.map((value) {
+        if (value is Map<String, dynamic>) {
+          return IdNameEntity.fromJson(value);
+        } else {
+          return null;
+        }
+      })
+          .where((item) => item != null)
+          .cast<IdNameEntity>()
+          .toList();
+
+      return result.convert<IdNameEntity>(list: list);
+    }
+    return result.convert<IdNameEntity>();
+  }
+
+}

+ 28 - 0
packages/cs_domain/lib/repository/facility_repository.g.dart

@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'facility_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$facilityRepositoryHash() =>
+    r'1844e210a274e96734c1217c2bf2d25278f67155';
+
+/// See also [facilityRepository].
+@ProviderFor(facilityRepository)
+final facilityRepositoryProvider = Provider<FacilityRepository>.internal(
+  facilityRepository,
+  name: r'facilityRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$facilityRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef FacilityRepositoryRef = ProviderRef<FacilityRepository>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 324 - 0
packages/cs_domain/lib/repository/form_repository.dart

@@ -0,0 +1,324 @@
+import 'dart:typed_data';
+
+import 'package:domain/entity/feedback_detail_entity.dart';
+import 'package:domain/entity/form_option_entity.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import '../constants/api_constants.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+import '../entity/form_content_entity.dart';
+import '../entity/form_detail_entity.dart';
+import '../entity/form_list_entity.dart';
+import '../entity/form_submitted_page_entity.dart';
+import '../entity/id_name_entity.dart';
+
+part 'form_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+FormRepository formRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return FormRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 表单的数据仓库
+ */
+class FormRepository {
+  DioEngine dioEngine;
+
+  FormRepository({required this.dioEngine});
+
+  /// 获取表单的可申请列表
+  Future<HttpResult<FormListEntity>> fetchFormApplyList({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormList,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final jsonList = result.getListJson();
+
+      //获取List数据 需要转换一次
+      var list = jsonList
+          ?.map((value) {
+            if (value is Map<String, dynamic>) {
+              return FormListEntity.fromJson(value);
+            } else {
+              return null;
+            }
+          })
+          .where((item) => item != null)
+          .cast<FormListEntity>()
+          .toList();
+
+      return result.convert<FormListEntity>(list: list);
+    }
+    return result.convert<FormListEntity>();
+  }
+
+  /// 已发布的表单列表
+  Future<HttpResult<FormSubmittedPageEntity>> fetchFormSubmitList({
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['page'] = curPage.toString();
+    params['limit'] = "10";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormSubmittedList,
+      params: params,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FormSubmittedPageEntity.fromJson(json!);
+      return result.convert<FormSubmittedPageEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 已批准的表单列表
+  Future<HttpResult<FormSubmittedPageEntity>> fetchFormApproveList({
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['page'] = curPage.toString();
+    params['limit'] = "10";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormApprovedList,
+      params: params,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FormSubmittedPageEntity.fromJson(json!);
+      return result.convert<FormSubmittedPageEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 已拒绝的表单列表
+  Future<HttpResult<FormSubmittedPageEntity>> fetchFormRejectList({
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['page'] = curPage.toString();
+    params['limit'] = "10";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormRejectedList,
+      params: params,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FormSubmittedPageEntity.fromJson(json!);
+      return result.convert<FormSubmittedPageEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 获取表单的选项
+  Future<HttpResult<FormOptionEntity>> fetchFormOption({
+    required String? typeId,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['type_id'] = typeId ?? "";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormOption,
+      params: params,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FormOptionEntity.fromJson(json!);
+      return result.convert<FormOptionEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 上传表单
+  Future<HttpResult> submitForm({
+    required String? estateFormId,
+    required String? typeId,
+    required FormContentEntity content,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    Map<String, String> paths = {};
+    params['estate_online_form_id'] = estateFormId ?? "";
+
+    //选择参数添加
+    if (Utils.isNotEmpty(content.typeOfApplication)) {
+      params["type_of_application"] = content.typeOfApplication!;
+    }
+
+    if (Utils.isNotEmpty(content.notesToRecipient)) {
+      params["notes_to_recipient"] = content.notesToRecipient!;
+    }
+
+    if (Utils.isNotEmpty(content.notesToManagement)) {
+      params["notes_to_management"] = content.notesToManagement!;
+    }
+
+    if (Utils.isNotEmpty(content.ownershipStatus)) {
+      params["ownership_status"] = content.ownershipStatus!;
+    }
+
+    if (Utils.isNotEmpty(content.vehicleNumber)) {
+      params["vehicle_number"] = content.vehicleNumber!;
+    }
+
+    if (Utils.isNotEmpty(content.iuNumber)) {
+      params["iu_number"] = content.iuNumber!;
+    }
+
+    if (Utils.isNotEmpty(content.vehicleMakeModelColour)) {
+      params["vehicle_make_model_colour"] = content.vehicleMakeModelColour!;
+    }
+
+    if (Utils.isNotEmpty(content.startDate)) {
+      params["start_date"] = content.startDate!;
+    }
+
+    if (Utils.isNotEmpty(content.endDate)) {
+      params["end_date"] = content.endDate!;
+    }
+
+    if (Utils.isNotEmpty(content.timeOrArrival)) {
+      params["time_or_arrival"] = "${content.timeOrArrival!}:00";
+    }
+
+    if (Utils.isNotEmpty(content.movingCompany)) {
+      params["moving_company"] = content.movingCompany!;
+    }
+
+    if (Utils.isNotEmpty(content.personInCharge)) {
+      params["person_in_charge"] = content.personInCharge!;
+    }
+
+    if (Utils.isNotEmpty(content.mobileNumber)) {
+      params["mobile_number"] = content.mobileNumber!;
+    }
+
+    if (Utils.isNotEmpty(content.companyAddress)) {
+      params["company_address"] = content.companyAddress!;
+    }
+
+    if (Utils.isNotEmpty(content.dateOfEntry)) {
+      params["date_of_entry"] = content.dateOfEntry!;
+    }
+
+    if (Utils.isNotEmpty(content.guestName)) {
+      params["guest_name"] = content.guestName!;
+    }
+
+    if (Utils.isNotEmpty(content.guestMobileNumber)) {
+      params["guest_mobile_number"] = content.guestMobileNumber!;
+    }
+
+    if (Utils.isNotEmpty(content.renovationStartDate)) {
+      params["renovation_start_date"] = content.renovationStartDate!;
+    }
+
+    if (Utils.isNotEmpty(content.renovationEndDate)) {
+      params["renovation_end_date"] = content.renovationEndDate!;
+    }
+
+    if (Utils.isNotEmpty(content.hackingStartDate)) {
+      params["hacking_start_date"] = content.hackingStartDate!;
+    }
+
+    if (Utils.isNotEmpty(content.hackingEndDate)) {
+      params["hacking_end_date"] = content.hackingEndDate!;
+    }
+
+    if (Utils.isNotEmpty(content.renovationCompany)) {
+      params["renovation_company"] = content.renovationCompany!;
+    }
+
+    if (Utils.isNotEmpty(content.listOfRenovationWorks)) {
+      params["list_of_renovation_works"] = content.listOfRenovationWorks!;
+    }
+
+    //attachments 添加
+    if (content.attachments != null && content.attachments!.isNotEmpty) {
+      content.attachments!.asMap().forEach((index, path) {
+        paths["attachments[$index]"] = path;
+      });
+    }
+
+    //signature 添加使用 ByteData 数据
+    Map<String, Uint8List> streams = {};
+    if (content.signatureByteData != null && content.signatureByteData is ByteData) {
+      streams["signature"] = (content.signatureByteData as ByteData).buffer.asUint8List();
+    }
+
+    final result = await dioEngine.requestNetResult(
+      "${ApiConstants.apiFormSubmit}$typeId",
+      params: params,
+      paths: paths,
+      pathStreams: streams,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 获取表单的详情数据
+  Future<HttpResult<FormDetailEntity>> fetchFormDetail({
+    required String? estateFormId,
+    required String? taskId,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['estate_online_form_id'] = estateFormId ?? "";
+    params['id'] = taskId ?? "";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFormDetail,
+      params: params,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FormDetailEntity.fromJson(json!);
+      return result.convert<FormDetailEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+}

+ 27 - 0
packages/cs_domain/lib/repository/form_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'form_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$formRepositoryHash() => r'36ca0be54f15596cd3dcc463d83d6b427140c64b';
+
+/// See also [formRepository].
+@ProviderFor(formRepository)
+final formRepositoryProvider = Provider<FormRepository>.internal(
+  formRepository,
+  name: r'formRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$formRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef FormRepositoryRef = ProviderRef<FormRepository>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 123 - 3
packages/cs_domain/lib/repository/main_repository.dart

@@ -1,15 +1,17 @@
-import 'package:domain/entity/auth_login_entity.dart';
-import 'package:domain/entity/server_time.dart';
+import 'package:domain/entity/feedback_detail_entity.dart';
 import 'package:plugin_platform/platform_export.dart';
 import 'package:plugin_platform/http/dio_engine.dart';
 import 'package:plugin_platform/http/http_result.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
-import 'package:shared/utils/util.dart';
+import 'package:shared/utils/log_utils.dart';
 
 import '../constants/api_constants.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:plugin_basic/provider/http_provider/http_provider.dart';
 
+import '../entity/feedback_list_entity.dart';
+import '../entity/id_name_entity.dart';
+
 part 'main_repository.g.dart';
 
 @Riverpod(keepAlive: true)
@@ -26,5 +28,123 @@ class MainRepository {
 
   MainRepository({required this.dioEngine});
 
+  /// 获取反馈的分类
+  Future<HttpResult<IdNameEntity>> fetchFeedbackCategory({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFeedbackCategory,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final jsonList = result.getListJson();
+
+      //获取List数据 需要转换一次
+      var list = jsonList
+          ?.map((value) {
+            if (value is Map<String, dynamic>) {
+              return IdNameEntity.fromJson(value);
+            } else {
+              return null;
+            }
+          })
+          .where((item) => item != null)
+          .cast<IdNameEntity>()
+          .toList();
+
+      return result.convert<IdNameEntity>(list: list);
+    }
+    return result.convert<IdNameEntity>();
+  }
+
+  /// 发布反馈
+  Future<HttpResult> postFeedback({
+    required String? categoryId,
+    required String? title,
+    required String? content,
+    List<String>? paths,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['category_id'] = categoryId!;
+    params['title'] = title!;
+    params['content'] = content!;
+
+    Map<String, String> files = {};
+    if (paths != null && paths.isNotEmpty) {
+      paths.asMap().forEach((index, path) {
+        files["resources[$index]"] = path;
+      });
+    }
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFeedbackPost,
+      params: params,
+      paths: files,
+      method: HttpMethod.POST,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 已发布的反馈列表
+  Future<HttpResult<FeedbackListEntity>> fetchFeedbackList({
+    required String status,
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['status'] = status;
+    params['page'] = curPage.toString();
+    params['limit'] = "10";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFeedbackList,
+      params: params,
+      method: HttpMethod.GET,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FeedbackListEntity.fromJson(json!);
+      return result.convert<FeedbackListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 获取反馈详情
+  Future<HttpResult<FeedbackDetailEntity>> fetchFeedbackDetail({
+    required String? id,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params['id'] = id??"";
+
+    final result = await dioEngine.requestNetResult(
+      ApiConstants.apiFeedbackDetail,
+      method: HttpMethod.GET,
+      params: params,
+      isShowLoadingDialog: true,
+      networkDebounce: true,
+      cancelToken: cancelToken,
+    );
 
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = FeedbackDetailEntity.fromJson(json!);
+      return result.convert<FeedbackDetailEntity>(data: data);
+    }
+    return result.convert();
+  }
 }

BIN
packages/cs_resources/assets/facility/active_icon.webp


BIN
packages/cs_resources/assets/facility/book_icon.webp


BIN
packages/cs_resources/assets/facility/deposit_icon.webp


+ 0 - 0
packages/cs_resources/assets/facility/function_room_icon.webp


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