Bladeren bron

新加坡的LabourRequest模块的重做

liukai 3 weken geleden
bovenliggende
commit
767a2f92bd
28 gewijzigde bestanden met toevoegingen van 2961 en 433 verwijderingen
  1. 0 1
      packages/cpt_auth/lib/modules/main/main_page.dart
  2. 1 1
      packages/cpt_labour_sg/lib/modules/job_list_edit/job_list_edit_page.dart
  3. 0 79
      packages/cpt_labour_sg/lib/modules/labour_request/labour_request_controller.dart
  4. 0 50
      packages/cpt_labour_sg/lib/modules/labour_request/labour_request_item.dart
  5. 0 174
      packages/cpt_labour_sg/lib/modules/labour_request/labour_request_page.dart
  6. 0 7
      packages/cpt_labour_sg/lib/modules/labour_request/labour_request_state.dart
  7. 245 0
      packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_controller.dart
  8. 441 0
      packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_page.dart
  9. 60 0
      packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_state.dart
  10. 364 0
      packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_filter.dart
  11. 269 0
      packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_item.dart
  12. 300 0
      packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_controller.dart
  13. 164 0
      packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_page.dart
  14. 18 0
      packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_state.dart
  15. 3 3
      packages/cpt_labour_sg/lib/router/labour_sg_service_impl.dart
  16. 9 3
      packages/cpt_labour_sg/lib/router/page_router.dart
  17. 3 0
      packages/cs_domain/lib/constants/api_constants.dart
  18. 2 0
      packages/cs_domain/lib/entity/response/labour_request_index_entity.dart
  19. 41 41
      packages/cs_domain/lib/entity/response/labour_request_list_entity.dart
  20. 142 0
      packages/cs_domain/lib/entity/response/labour_request_s_g_edit_index_entity.dart
  21. 57 0
      packages/cs_domain/lib/entity/response/labour_request_s_g_list_entity.dart
  22. 26 0
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  23. 8 0
      packages/cs_domain/lib/generated/json/labour_request_index_entity.g.dart
  24. 388 0
      packages/cs_domain/lib/generated/json/labour_request_s_g_edit_index_entity.g.dart
  25. 129 0
      packages/cs_domain/lib/generated/json/labour_request_s_g_list_entity.g.dart
  26. 289 73
      packages/cs_domain/lib/repository/labour_sg_repository.dart
  27. 1 1
      packages/cs_plugin_platform/lib/engine/network/network_engine.dart
  28. 1 0
      packages/cs_router/lib/path/router_path.dart

+ 0 - 1
packages/cpt_auth/lib/modules/main/main_page.dart

@@ -26,7 +26,6 @@ import 'main_state.dart';
 
 /*
    App首页页面
-   底部5个 Tab + PageView 切换
  */
 class MainPage extends BaseStatefulPage<MainController> {
   MainPage({super.key});

+ 1 - 1
packages/cpt_labour_sg/lib/modules/job_list_edit/job_list_edit_page.dart

@@ -25,7 +25,7 @@ import 'package:router/path/router_path.dart';
 import 'job_list_edit_state.dart';
 
 /*
- * 新加坡的工作详情,其实就是LabourRequest的详情和编辑
+ * 新加坡的工作详情,与LabourRequest的详情和编辑类似
  */
 class JobListEditPage extends BaseStatelessPage<JobListEditController> {
   JobListEditPage({Key? key}) : super(key: key);

+ 0 - 79
packages/cpt_labour_sg/lib/modules/labour_request/labour_request_controller.dart

@@ -1,79 +0,0 @@
-import 'package:domain/entity/response/labour_request_s_g_entity.dart';
-import 'package:domain/repository/labour_sg_repository.dart';
-import 'package:get/get.dart';
-import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
-import 'package:shared/utils/date_time_utils.dart';
-import 'package:widgets/load_state_layout.dart';
-import 'package:widgets/picker/date_picker_util.dart';
-
-import '../labour_request_add/labour_request_add_page.dart';
-import 'labour_request_state.dart';
-
-class LabourRequestController extends GetxController with DioCancelableMixin {
-  final LabourSGRepository _labourRepository = Get.find();
-  final LabourRequestState state = LabourRequestState();
-
-  //页面PlaceHolder的展示
-  LoadState loadingState = LoadState.State_Success;
-  String? errorMessage;
-
-  //刷新页面状态
-  void changeLoadingState(LoadState state) {
-    loadingState = state;
-    update();
-  }
-
-  void retryRequest() {
-    fetchLabourRequestMain();
-  }
-
-  //去创建页面
-  void gotoLabourRequestAddPage() {
-    LabourRequestAddPage.startInstance((result) {
-      if (result is bool) {
-        //添加成功之后刷新
-        fetchLabourRequestMain();
-      }
-    });
-  }
-
-  // 获取首页数据
-  void fetchLabourRequestMain() async {
-    changeLoadingState(LoadState.State_Loading);
-
-    var result = await _labourRepository.fetchLabourRequestMain(
-      DateTimeUtils.formatDate(state.selectedDateTime, format: "yyyy-MM-dd"),
-      cancelToken: cancelToken,
-    );
-
-    if (result.isSuccess) {
-      // state.datas = result.data?.countList ?? [];
-      state.datas = result.list
-          ?.whereType<LabourRequestSGCountList>() // 直接过滤出非 null 的 StaffRequestReportEntity
-          .toList() ??[];
-      changeLoadingState(LoadState.State_Success);
-    } else {
-      errorMessage = result.errorMsg ?? "Network Load Error".tr;
-      changeLoadingState(LoadState.State_Error);
-    }
-  }
-
-  @override
-  void onReady() {
-    super.onReady();
-    fetchLabourRequestMain();
-  }
-
-  /// 筛选开始日期
-  void pickerSelectDate() {
-    DatePickerUtil.showCupertinoDatePicker(
-      selectedDateTime: state.selectedDateTime,
-      onDateTimeChanged: (date) {
-        state.selectedDateTime = date;
-        update();
-        fetchLabourRequestMain();
-      },
-      title: "Select Date".tr,
-    );
-  }
-}

+ 0 - 50
packages/cpt_labour_sg/lib/modules/labour_request/labour_request_item.dart

@@ -1,50 +0,0 @@
-import 'package:cs_resources/constants/color_constants.dart';
-import 'package:domain/entity/response/labour_request_s_g_entity.dart';
-import 'package:flutter/material.dart';
-import 'package:plugin_basic/basic_export.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/my_text_view.dart';
-
-/*
- * 用工请求Item(新加坡)
- */
-class LabourRequestItem extends StatelessWidget {
-  final LabourRequestSGCountList item;
-  final void Function(String? date) onDateAction;
-
-  const LabourRequestItem({super.key,
-    required this.item,
-    required this.onDateAction,
-  });
-
-  @override
-  Widget build(BuildContext context) {
-    return Row(
-      children: [
-        MyTextView(
-          "[${item.week}] ${item.date}",
-          isFontRegular: true,
-          fontSize: 16,
-          textAlign: TextAlign.start,
-          marginLeft: 34,
-          textColor: item.today ? ColorConstants.textGreen0AC074 : Colors.white,
-        ).expanded(flex: 6),
-        MyTextView(
-          "${item.realNum}/${item.hiringNum}",
-          isFontBold: true,
-          fontSize: 16,
-          textAlign: TextAlign.right,
-          marginRight: 50,
-          textDecoration: TextDecoration.underline,
-          decorationColor: ColorConstants.textYellowFFBB1B,
-          decorationThickness: 2.0,
-          decorationStyle: TextDecorationStyle.solid,
-          textColor: ColorConstants.textYellowFFBB1B,
-          onClick: (){
-            onDateAction.call(item.date);
-          },
-        ).expanded(flex: 4),
-      ],
-    ).paddingOnly(top: 7, bottom: 7);
-  }
-}

+ 0 - 174
packages/cpt_labour_sg/lib/modules/labour_request/labour_request_page.dart

@@ -1,174 +0,0 @@
-import 'package:cpt_labour_sg/modules/job_list/job_list_page.dart';
-import 'package:cs_resources/constants/color_constants.dart';
-import 'package:cs_resources/generated/assets.dart';
-import 'package:flutter/material.dart';
-import 'package:get/get.dart';
-import 'package:shared/utils/date_time_utils.dart';
-import 'package:shared/utils/screen_util.dart';
-import 'package:widgets/ext/ex_widget.dart';
-import 'package:widgets/load_state_layout.dart';
-import 'package:widgets/my_appbar.dart';
-import 'package:widgets/my_button.dart';
-import 'package:widgets/my_load_image.dart';
-import 'package:widgets/my_text_view.dart';
-
-import 'labour_request_controller.dart';
-
-import 'package:plugin_basic/base/base_stateless_page.dart';
-import 'package:plugin_basic/utils/ext_get_nav.dart';
-import 'package:router/path/router_path.dart';
-
-import 'labour_request_item.dart';
-import 'labour_request_state.dart';
-
-class LabourRequestPage extends BaseStatelessPage<LabourRequestController> {
-  LabourRequestPage({Key? key}) : super(key: key);
-
-  //启动当前页面
-  static void startInstance() {
-    return Get.start(RouterPath.labourRequestSG);
-  }
-
-  late LabourRequestState state;
-
-  @override
-  void initState() {
-    state = controller.state;
-  }
-
-  @override
-  LabourRequestController createRawController() {
-    return LabourRequestController();
-  }
-
-  @override
-  Widget buildWidget(BuildContext context) {
-    return autoCtlGetBuilder(builder: (controller) {
-      return Scaffold(
-        extendBodyBehindAppBar: true,
-        appBar: MyAppBar.appBar(context, "Labour Request".tr),
-        body: SafeArea(
-          bottom: true,
-          top: false,
-          child: Container(
-            width: double.infinity,
-            height: double.infinity,
-            padding: EdgeInsets.only(top: kToolbarHeight + ScreenUtil.getStatusBarH(context) + 1),
-            decoration: const BoxDecoration(
-              gradient: LinearGradient(
-                colors: [
-                  Color(0xFF091D44),
-                  Color(0xFF245A8A),
-                  Color(0xFF7F7CEC),
-                ],
-                begin: Alignment.topCenter,
-                end: Alignment.bottomCenter,
-              ),
-            ),
-            child: Column(
-              children: [
-                // 搜索的布局
-                Container(
-                  width: double.infinity,
-                  height: 42,
-                  margin: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
-                  padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 13.5),
-                  decoration: BoxDecoration(
-                    color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
-                    borderRadius: BorderRadius.circular(20.0), // 设置圆角
-                  ),
-                  child: Row(
-                    children: [
-                      const MyAssetImage(Assets.cptJobPickDateIcon, width: 15, height: 15),
-                      MyTextView(
-                        DateTimeUtils.formatDate(state.selectedDateTime, format: "yyyy-MM-dd"),
-                        hint: "Select Date".tr,
-                        textHintColor: ColorConstants.textGrayAECAE5,
-                        fontSize: 15,
-                        marginLeft: 9.5,
-                        isFontRegular: true,
-                        textColor: ColorConstants.textGrayAECAE5,
-                      ),
-                    ],
-                  ).onTap(() {
-                    controller.pickerSelectDate();
-                  }),
-                ),
-
-                //添加用工请求按钮
-                MyButton(
-                  type: ClickType.throttle,
-                  milliseconds: 500,
-                  onPressed: () {
-                    FocusScope.of(context).unfocus();
-                    controller.gotoLabourRequestAddPage();
-                  },
-                  text: "Create New Job Request".tr,
-                  textColor: ColorConstants.white,
-                  fontSize: 16,
-                  radius: 20,
-                  backgroundColor: hexToColor("#FFBB1B"),
-                  fontWeight: FontWeight.w500,
-                ).marginOnly(left: 15, right: 15),
-
-                Container(
-                  width: double.infinity,
-                  margin: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
-                  decoration: BoxDecoration(
-                    color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
-                    borderRadius: BorderRadius.circular(5.0), // 设置圆角
-                  ),
-                  child: Column(
-                    children: [
-                      Row(
-                        children: [
-                          MyTextView(
-                            "Date".tr,
-                            isFontBold: true,
-                            fontSize: 16,
-                            textAlign: TextAlign.center,
-                            textColor: Colors.white,
-                          ).expanded(flex: 5),
-                          MyTextView(
-                            "YY Circle".tr,
-                            isFontBold: true,
-                            fontSize: 16,
-                            textAlign: TextAlign.right,
-                            marginRight: 32,
-                            textColor: Colors.white,
-                          ).expanded(flex: 5),
-                        ],
-                      ).constrained(height: 45),
-
-                      //分割线
-                      const Divider(color: ColorConstants.dividerBar, height: 0.5),
-
-                      //底部的数据
-                      LoadStateLayout(
-                        state: controller.loadingState,
-                        errorMessage: controller.errorMessage,
-                        errorRetry: () {
-                          controller.retryRequest();
-                        },
-                        successWidget: Column(
-                          children: state.datas.map((item) {
-                            return LabourRequestItem(
-                              item: item,
-                              onDateAction: (date) {
-                                JobListPage.startInstance(date: date);
-                              },
-                            );
-                          }).toList(),
-                        ).paddingOnly(top: 14, bottom: 7),
-                      ).constrained(width: double.infinity, height: 291),
-                    ],
-                  ),
-                ).constrained(minHeight: 336.5),
-              ],
-            ),
-          ),
-        ),
-      );
-    });
-  }
-}

+ 0 - 7
packages/cpt_labour_sg/lib/modules/labour_request/labour_request_state.dart

@@ -1,7 +0,0 @@
-import 'package:domain/entity/response/labour_request_s_g_entity.dart';
-
-class LabourRequestState {
-
-  DateTime? selectedDateTime;
-  List<LabourRequestSGCountList> datas = [];
-}

+ 245 - 0
packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_controller.dart

@@ -0,0 +1,245 @@
+import 'package:domain/repository/labour_sg_repository.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/engine/loading/loading_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/picker/date_picker_util.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+
+import 'labour_request_edit_state.dart';
+
+class LabourRequestEditController extends GetxController with DioCancelableMixin {
+  final LabourSGRepository _labourRepository = Get.find();
+  final LabourRequestEditState state = LabourRequestEditState();
+
+  // 获取添加选项数据
+  void fetchLabourRequestAddIndex() async {
+    LoadingEngine.show();
+    var result = await _labourRepository.fetchLabourRequestAddIndex(
+      isShowLoadingDialog: false,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      state.indexEntity = result.data;
+      update();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+
+    var result2 = await _labourRepository.fetchLabourRequestEditDetail(
+      isShowLoadingDialog: false,
+      state.requestId,
+      cancelToken: cancelToken,
+    );
+
+    LoadingEngine.dismiss();
+
+    if (result2.isSuccess) {
+      state.editIndexEntity = result2.data;
+      var needMallController = state.formData['need_male']!['controller'];
+      var needFemaleController = state.formData['need_female']!['controller'];
+      var needNumController = state.formData['need_no']!['controller'];
+      var remarkController = state.formData['remark']!['controller'];
+
+      // int genderOptionType = 0;  //使用哪一种类型限制
+      if (state.editIndexEntity?.job?.genderNumberLimit == 1) {
+        state.genderOptionType = 1;
+        needMallController.text = state.editIndexEntity?.job?.maleNumberLimit?.toString();
+        needFemaleController.text = state.editIndexEntity?.job?.femaleNumberLimit?.toString();
+        needNumController.text = '';
+      } else {
+        state.genderOptionType = 0;
+        needMallController.text = '';
+        needFemaleController.text = '';
+        needNumController.text = state.editIndexEntity?.job?.needNum?.toString();
+      }
+
+      remarkController.text = state.editIndexEntity?.remark ?? '';
+
+      state.selectedJobTitle = state.editIndexEntity?.job?.jobTitle;
+      state.selectedJobTitleId = state.editIndexEntity?.job?.jobTitleId?.toString();
+
+      state.selectedStartTime = DateTimeUtils.getDateTime(state.editIndexEntity!.startTime!);
+      state.selectedEndTime = DateTimeUtils.getDateTime(state.editIndexEntity!.endTime!);
+
+      state.selectedOutlet = state.editIndexEntity?.job?.outletName;
+      state.selectedOutletId = state.editIndexEntity?.job?.outletId?.toString();
+
+      state.selectRequestTypeId = state.editIndexEntity?.job?.requestType?.toString();
+
+      // String? selectRequestTypeId;
+
+      update();
+    } else {
+      ToastEngine.show(result2.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchLabourRequestAddIndex();
+  }
+
+  // 选择工标题
+  void pickJobTitle() {
+    if (state.indexEntity == null) {
+      return;
+    }
+
+    int selectedTemplateIndex;
+    if (state.selectedJobTitleId == null) {
+      selectedTemplateIndex = 0;
+    } else {
+      selectedTemplateIndex = state.indexEntity!.titleList.indexWhere((department) => department.value.toString() == state.selectedJobTitleId);
+    }
+
+    if (selectedTemplateIndex < 0) {
+      selectedTemplateIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.indexEntity!.titleList.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedTemplateIndex,
+      onPickerChanged: (_, index) {
+        state.selectedJobTitleId = state.indexEntity!.titleList[index].value!.toString();
+        state.selectedJobTitle = state.indexEntity!.titleList[index].txt!.toString();
+        update();
+      },
+    );
+  }
+
+  //选择开始时间
+  void pickStartTime() {
+    if (state.indexEntity == null) {
+      return;
+    }
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: state.selectedStartTime,
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.selectedStartTime = date;
+        update();
+      },
+      title: "Start Time".tr,
+    );
+  }
+
+  // 选择结束时间
+  void pickEndTime() {
+    if (state.indexEntity == null) {
+      return;
+    }
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: state.selectedEndTime ?? state.selectedStartTime,
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.selectedEndTime = date;
+        update();
+      },
+      title: "End Time".tr,
+    );
+  }
+
+  //选择部门
+  void pickOutlet() {
+    if (state.indexEntity == null) {
+      return;
+    }
+
+    int selectedIndex;
+    if (state.selectedOutletId == null) {
+      selectedIndex = 0;
+    } else {
+      selectedIndex = state.indexEntity!.outletList.indexWhere((department) => department.value.toString() == state.selectedOutletId);
+    }
+
+    if (selectedIndex < 0) {
+      selectedIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.indexEntity!.outletList.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedIndex,
+      onPickerChanged: (_, index) {
+        state.selectedOutletId = state.indexEntity!.outletList[index].value!.toString();
+        state.selectedOutlet = state.indexEntity!.outletList[index].txt!.toString();
+        update();
+      },
+    );
+  }
+
+  // 提交LabourRequest表单
+  void doEditSubmit() async {
+    var maleNoController = state.formData['need_male']!['controller'];
+    var femaleNoController = state.formData['need_female']!['controller'];
+    var needNoController = state.formData['need_no']!['controller'];
+    var remarkController = state.formData['remark']!['controller'];
+
+    String maleNo = maleNoController.text.toString();
+    String femaleNo = femaleNoController.text.toString();
+    String needNo = needNoController.text.toString();
+    String remark = remarkController.text.toString();
+
+    if (state.selectedStartTime == null) {
+      ToastEngine.show("Select Job Start Time".tr);
+      return;
+    }
+
+    if (state.selectedEndTime == null) {
+      ToastEngine.show("Select Job End Time".tr);
+      return;
+    }
+
+    if (Utils.isEmpty(state.selectedOutletId)) {
+      ToastEngine.show("Choose Outlet".tr);
+      return;
+    }
+
+    if (state.genderOptionType == 0) {
+      if (Utils.isEmpty(needNo)) {
+        ToastEngine.show("Enter No. of Staff".tr);
+        return;
+      }
+    } else {
+      if (Utils.isEmpty(maleNo) || Utils.isEmpty(femaleNo)) {
+        ToastEngine.show("Enter No. of Staff of The Corresponding Gender".tr);
+        return;
+      }
+    }
+
+    var result = await _labourRepository.submitLabourRequestEdit(
+      state.requestId,
+      DateTimeUtils.formatDate(state.selectedStartTime),
+      DateTimeUtils.formatDate(state.selectedEndTime),
+      state.selectedOutletId,
+      state.genderOptionType,
+      maleNo,
+      femaleNo,
+      needNo,
+      state.selectRequestTypeId,
+      remark,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      //根据类型刷新
+      state.cb?.call(true);
+
+      Get.back();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+}

+ 441 - 0
packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_page.dart

@@ -0,0 +1,441 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:get/get.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/screen_util.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_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/no_shadow_scroll_behavior.dart';
+import 'package:widgets/shatter/custom_radio_check.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/round_my_text_field.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'labour_request_edit_controller.dart';
+
+import 'package:plugin_basic/base/base_stateless_page.dart';
+import 'package:plugin_basic/utils/ext_get_nav.dart';
+import 'package:router/path/router_path.dart';
+
+import 'labour_request_edit_state.dart';
+
+class LabourRequestEditPage extends BaseStatelessPage<LabourRequestEditController> {
+  LabourRequestEditPage({Key? key}) : super(key: key);
+
+  //启动当前页面,pageType  1是编辑  2是详情
+  static void startInstance(int pageType, String? requestId, void Function(dynamic value)? cb) {
+    return Get.start(RouterPath.labourRequestEditSG, arguments: {'pageType': pageType, 'requestId': requestId, 'cb': cb});
+  }
+
+  late LabourRequestEditState state;
+
+  @override
+  void initState() {
+    state = controller.state;
+    state.pageType = Get.arguments['pageType'];
+    state.requestId = Get.arguments['requestId'];
+    state.cb = Get.arguments['cb'] as void Function(dynamic)?;
+  }
+
+  @override
+  LabourRequestEditController createRawController() {
+    return LabourRequestEditController();
+  }
+
+  @override
+  Widget buildWidget(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appBar(context, state.pageType == 1 ? "Edit Labour Requisition".tr : "Labour Requisition".tr),
+        body: SafeArea(
+          bottom: true,
+          top: false,
+          child: Container(
+            width: double.infinity,
+            height: double.infinity,
+            padding: EdgeInsets.only(top: kToolbarHeight + ScreenUtil.getStatusBarH(context) + 1),
+            decoration: const BoxDecoration(
+              gradient: LinearGradient(
+                colors: [
+                  Color(0xFF091D44),
+                  Color(0xFF245A8A),
+                  Color(0xFF7F7CEC),
+                ],
+                begin: Alignment.topCenter,
+                end: Alignment.bottomCenter,
+              ),
+            ),
+            child: Scrollbar(
+              child: ScrollConfiguration(
+                behavior: NoShadowScrollBehavior(),
+                child: SingleChildScrollView(
+                  scrollDirection: Axis.vertical,
+                  physics: const BouncingScrollPhysics(),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      //工作标题,选择模板
+                      FormRequireText(
+                        text: "Job Title".tr,
+                      ).marginOnly(top: 15),
+
+                      //工作标题
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.5),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.selectedJobTitle ?? "",
+                              fontSize: 14,
+                              hint: "Choose Job Title".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+
+                            //下拉选图标
+                            Visibility(
+                              visible: state.pageType != 2,
+                              child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                            ),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                      }),
+
+                      //选择工作时间
+                      FormRequireText(
+                        text: "Job Time".tr,
+                      ).marginOnly(top: 15),
+
+                      Row(
+                        mainAxisSize: MainAxisSize.max,
+                        crossAxisAlignment: CrossAxisAlignment.center,
+                        mainAxisAlignment: MainAxisAlignment.start,
+                        children: [
+                          //选择工作开始时间
+                          Expanded(
+                            child: Container(
+                              padding: const EdgeInsets.only(left: 16, right: 10),
+                              height: 45,
+                              decoration: BoxDecoration(
+                                color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                                borderRadius: const BorderRadius.all(Radius.circular(5)),
+                              ),
+                              child: Row(
+                                mainAxisSize: MainAxisSize.max,
+                                crossAxisAlignment: CrossAxisAlignment.center,
+                                mainAxisAlignment: MainAxisAlignment.start,
+                                children: [
+                                  MyTextView(
+                                    state.selectedStartTime == null ? "" : DateTimeUtils.formatDate(state.selectedStartTime, format: "yyyy-MM-dd HH:mm"),
+                                    fontSize: 14,
+                                    hint: "Job Start Time".tr,
+                                    textHintColor: ColorConstants.textGrayAECAE5,
+                                    isFontMedium: true,
+                                    textColor: ColorConstants.white,
+                                  ).expanded(),
+                                  //下拉选图标
+                                  Visibility(
+                                    visible: state.pageType != 2,
+                                    child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                                  ),
+                                ],
+                              ),
+                            ).onTap(() {
+                              FocusScope.of(context).unfocus();
+                              if (state.pageType != 2) controller.pickStartTime();
+                            }),
+                          ),
+
+                          //选择工作结束时间
+                          Expanded(
+                            child: Container(
+                              padding: const EdgeInsets.only(left: 16, right: 10),
+                              margin: const EdgeInsets.only(left: 10),
+                              height: 45,
+                              decoration: BoxDecoration(
+                                color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                                borderRadius: const BorderRadius.all(Radius.circular(5)),
+                              ),
+                              child: Row(
+                                mainAxisSize: MainAxisSize.max,
+                                crossAxisAlignment: CrossAxisAlignment.center,
+                                mainAxisAlignment: MainAxisAlignment.start,
+                                children: [
+                                  MyTextView(
+                                    state.selectedEndTime == null ? "" : DateTimeUtils.formatDate(state.selectedEndTime, format: "yyyy-MM-dd HH:mm"),
+                                    fontSize: 14,
+                                    hint: "Job End Time".tr,
+                                    textHintColor: ColorConstants.textGrayAECAE5,
+                                    isFontMedium: true,
+                                    textColor: ColorConstants.white,
+                                  ).expanded(),
+                                  //下拉选图标
+                                  Visibility(
+                                    visible: state.pageType != 2,
+                                    child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                                  ),
+                                ],
+                              ),
+                            ).onTap(() {
+                              FocusScope.of(context).unfocus();
+                              if (state.pageType != 2) controller.pickEndTime();
+                            }),
+                          ),
+                        ],
+                      ).marginOnly(top: 10),
+
+                      //工作选择部门
+                      FormRequireText(
+                        text: "Outlet".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择部门
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.selectedOutlet ?? "",
+                              fontSize: 14,
+                              hint: "Choose Outlet".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            Visibility(
+                              visible: state.pageType != 2,
+                              child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                            ),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        if (state.pageType != 2) controller.pickOutlet();
+                      }),
+
+                      //需要的人数
+                      FormRequireText(
+                        text: "No. of Staff".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择人数类型单选
+                      CustomRadioCheck(
+                        options: state.genderOptions,
+                        enable: state.pageType != 2,
+                        onOptionSelected: (index, text) {
+                          state.genderOptionType = index;
+                          controller.update();
+                        },
+                        selectedPosition: state.genderOptionType,
+                      ).marginOnly(top: 10),
+
+                      //输入框(只允许输入数字)
+                      Visibility(
+                        visible: state.genderOptionType == 0,
+                        child: CustomTextField(
+                          formKey: "need_no",
+                          marginLeft: 0,
+                          marginRight: 0,
+                          paddingTop: 0,
+                          paddingBottom: 0,
+                          height: 45,
+                          fillBackgroundColor: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                          enabled: state.pageType != 2,
+                          inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
+                          textInputType: TextInputType.number,
+                          formData: state.formData,
+                          textInputAction: TextInputAction.done,
+                          onSubmit: (key, value) {
+                            FocusScope.of(context).unfocus();
+                          },
+                          marginTop: 10,
+                        ),
+                      ),
+
+                      Visibility(
+                        visible: state.genderOptionType != 0,
+                        child: Row(
+                          children: [
+                            MyTextView(
+                              "Male".tr,
+                              fontSize: 15,
+                              isFontRegular: true,
+                              marginRight: 10,
+                              textColor: ColorConstants.textGrayAECAE5,
+                            ),
+                            CustomTextField(
+                              formKey: "need_male",
+                              marginLeft: 0,
+                              marginRight: 0,
+                              paddingTop: 0,
+                              paddingBottom: 0,
+                              height: 45,
+                              fillBackgroundColor: const Color(0xFF4DCFF6).withOpacity(0.2),
+                              inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
+                              textInputType: TextInputType.number,
+                              formData: state.formData,
+                              textInputAction: TextInputAction.done,
+                              onSubmit: (key, value) {
+                                FocusScope.of(context).unfocus();
+                              },
+                            ).expanded(),
+                            MyTextView(
+                              "Female".tr,
+                              fontSize: 15,
+                              isFontRegular: true,
+                              marginLeft: 12,
+                              marginRight: 10,
+                              textColor: ColorConstants.textGrayAECAE5,
+                            ),
+                            CustomTextField(
+                              formKey: "need_female",
+                              marginLeft: 0,
+                              marginRight: 0,
+                              paddingTop: 0,
+                              paddingBottom: 0,
+                              height: 45,
+                              fillBackgroundColor: const Color(0xFF4DCFF6).withOpacity(0.2),
+                              inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
+                              textInputType: TextInputType.number,
+                              formData: state.formData,
+                              textInputAction: TextInputAction.done,
+                              onSubmit: (key, value) {
+                                FocusScope.of(context).unfocus();
+                              },
+                            ).expanded(),
+                          ],
+                        ).marginOnly(top: 10),
+                      ),
+
+                      //Request Type
+                      MyTextView(
+                        "Request Type".tr,
+                        fontSize: 15,
+                        isFontRegular: true,
+                        textColor: Colors.white,
+                        marginTop: 15,
+                      ),
+
+                      //Request Type单选
+                      CustomRadioCheck(
+                        options: state.indexEntity?.requestType.map((e) => e.txt!).toList() ?? [],
+                        enable: state.pageType != 2,
+                        onOptionSelected: (index, text) {
+                          state.selectRequestTypeId = state.indexEntity!.requestType[index].value;
+                        },
+                        selectedPosition: state.indexEntity == null
+                            ? -1
+                            : Utils.isEmpty(state.selectRequestTypeId)
+                                ? 0
+                                : state.indexEntity!.requestType.indexWhere((e) => e.value.toString() == state.selectRequestTypeId),
+                      ).marginOnly(top: 10),
+
+                      //输入Remark
+                      MyTextView(
+                        "Remark".tr,
+                        fontSize: 15,
+                        isFontRegular: true,
+                        textColor: Colors.white,
+                        marginTop: 15,
+                      ),
+
+                      IgnoreKeyboardDismiss(
+                        child: Container(
+                          height: 160,
+                          margin: const EdgeInsets.only(top: 10),
+                          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                          decoration: BoxDecoration(
+                            color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                            borderRadius: const BorderRadius.all(Radius.circular(5)),
+                          ),
+                          child: TextField(
+                            cursorColor: ColorConstants.white,
+                            cursorWidth: 1.5,
+                            autofocus: false,
+                            enabled: state.pageType != 2,
+                            focusNode: state.formData["remark"]!['focusNode'],
+                            controller: state.formData["remark"]!['controller'],
+                            // 装饰
+                            decoration: InputDecoration(
+                              isDense: true,
+                              isCollapsed: true,
+                              border: InputBorder.none,
+                              hintText: state.formData["remark"]!['hintText'],
+                              hintStyle: const TextStyle(
+                                color: ColorConstants.textGrayAECAE5,
+                                fontSize: 15.0,
+                                fontWeight: FontWeight.w400,
+                              ),
+                            ),
+                            style: const TextStyle(
+                              color: ColorConstants.white,
+                              fontSize: 15.0,
+                              fontWeight: FontWeight.w400,
+                            ),
+                            // 键盘动作右下角图标
+                            textInputAction: TextInputAction.done,
+                            onSubmitted: (value) {
+                              FocusScope.of(context).unfocus();
+                            },
+                          ),
+                        ),
+                      ).marginOnly(bottom: 30),
+
+                      //提交按钮
+                      Visibility(
+                        visible: state.pageType != 2,
+                        child: MyButton(
+                          type: ClickType.throttle,
+                          milliseconds: 500,
+                          onPressed: () {
+                            FocusScope.of(context).unfocus();
+                            controller.doEditSubmit();
+                          },
+                          text: "Submit".tr,
+                          textColor: ColorConstants.white,
+                          fontSize: 16,
+                          radius: 22.5,
+                          backgroundColor: hexToColor("#FFBB1B"),
+                          fontWeight: FontWeight.w500,
+                        ).marginOnly(bottom: 30),
+                      ),
+                    ],
+                  ).paddingOnly(left: 15, right: 15),
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 60 - 0
packages/cpt_labour_sg/lib/modules/labour_request_edit/labour_request_edit_state.dart

@@ -0,0 +1,60 @@
+import 'package:domain/entity/response/labour_request_s_g_add_index_entity.dart';
+import 'package:domain/entity/response/labour_request_s_g_edit_index_entity.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
+import 'package:shared/utils/date_time_utils.dart';
+
+class LabourRequestEditState {
+  //表单的校验与数据
+  Map<String, Map<String, dynamic>> formData = {
+    'need_male': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Needs Num'.tr,
+      'obsecure': false,
+    },
+    'need_female': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Needs Num'.tr,
+      'obsecure': false,
+    },
+    'need_no': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Needs Num'.tr,
+      'obsecure': false,
+    },
+    'remark': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter...'.tr,
+      'obsecure': false,
+    },
+  };
+
+  int pageType = 2;  //页面的状态 1是编辑  2是详情
+  String? requestId;  //编辑和详情需要用到ID
+  void Function(dynamic value)? cb;
+
+  List<String> genderOptions = ["Gender Unlimited".tr, "Gender Limited".tr];
+  int genderOptionType = 0;  //使用哪一种类型限制
+
+  LabourRequestSGAddIndexEntity? indexEntity;
+  LabourRequestSGEditIndexEntity? editIndexEntity;
+
+  String? selectedJobTitle;
+  String? selectedJobTitleId;
+
+  DateTime? selectedStartTime;
+  DateTime? selectedEndTime;
+
+  String? selectedOutlet;
+  String? selectedOutletId;
+
+  String? selectRequestTypeId;
+}

+ 364 - 0
packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_filter.dart

@@ -0,0 +1,364 @@
+import 'dart:typed_data';
+import 'dart:ui';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/labour_request_index_entity.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:get/get.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/picker/date_picker_util.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import 'package:widgets/widget_export.dart';
+
+/*
+ * 用工请求列表的筛选
+ */
+class LabourRequestFilter extends StatefulWidget {
+  void Function(DateTime? selectedStartDate, DateTime? selectedEndDate, String? selectedStatusId, String? selectedDepartmentId)? onFilterAction;
+  LabourRequestIndexEntity optionResult;
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+  String? selectedStatusId;
+  String? selectedDepartmentId;
+
+  LabourRequestFilter({
+    required this.optionResult,
+    required this.selectedStartDate,
+    required this.selectedEndDate,
+    required this.selectedStatusId,
+    required this.selectedDepartmentId,
+    this.onFilterAction,
+  });
+
+  @override
+  State<LabourRequestFilter> createState() => _LabourRequestFilterState();
+}
+
+class _LabourRequestFilterState extends State<LabourRequestFilter> {
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+  String? selectedStatusId;
+  String? selectedDepartmentId;
+
+  @override
+  void initState() {
+    super.initState();
+    this.selectedStartDate = widget.selectedStartDate;
+    this.selectedEndDate = widget.selectedEndDate;
+    this.selectedStatusId = widget.selectedStatusId;
+    this.selectedDepartmentId = widget.selectedDepartmentId;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      mainAxisAlignment: MainAxisAlignment.start,
+      children: [
+        SizedBox(
+          height: kToolbarHeight + ScreenUtil.getStatusBarH(context) + 1,
+        ),
+        Container(
+          padding: const EdgeInsets.only(left: 15, right: 15, top: 17.5, bottom: 20),
+          width: double.infinity,
+          decoration: const BoxDecoration(
+            color: Colors.white,
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //部门
+              MyTextView(
+                "Outlet".tr,
+                fontSize: 14,
+                isFontMedium: true,
+                textColor: ColorConstants.black33,
+              ),
+
+              //选择部门
+              Container(
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: const BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedDepartmentId == null || selectedDepartmentId == "0"
+                          ? ""
+                          : (widget.optionResult.departmentList?.isEmpty == true ? widget.optionResult.outletList : widget.optionResult.departmentList)!
+                              .firstWhere((element) => element.value.toString() == selectedDepartmentId)
+                              .txt!,
+                      hint: "Choose Outlet".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      fontSize: 14,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                  ],
+                ),
+              ).onTap(() {
+                pickerOutlet();
+              }),
+
+              //状态
+              MyTextView(
+                "Status".tr,
+                fontSize: 14,
+                isFontMedium: true,
+                marginTop: 11,
+                textColor: ColorConstants.black33,
+              ),
+
+              //选择状态
+              Container(
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: const BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedStatusId == null || selectedStatusId == "0"
+                          ? ""
+                          : widget.optionResult.statusList!.firstWhere((element) => element.value.toString() == selectedStatusId).txt!,
+                      fontSize: 14,
+                      hint: "Choose Status".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                  ],
+                ),
+              ).onTap(() {
+                pickerStatus();
+              }),
+
+              //开始时间
+              MyTextView(
+                "Start Date".tr,
+                fontSize: 14,
+                isFontMedium: true,
+                marginTop: 11,
+                textColor: ColorConstants.black33,
+              ),
+
+              //选择时间
+              Container(
+                padding: EdgeInsets.only(left: 16, right: 10),
+                margin: EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedStartDate == null ? "" : DateTimeUtils.formatDate(selectedStartDate, format: "yyyy-MM-dd"),
+                      fontSize: 14,
+                      hint: "Choose Start Date".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                  ],
+                ),
+              ).onTap(() {
+                pickerStartDate();
+              }),
+
+              //结束日期
+              MyTextView(
+                "End Date".tr,
+                fontSize: 14,
+                marginTop: 11,
+                isFontMedium: true,
+                textColor: ColorConstants.black33,
+              ),
+
+              //选择结束日期
+              Container(
+                padding: EdgeInsets.only(left: 16, right: 10),
+                margin: EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedEndDate == null ? "" : DateTimeUtils.formatDate(selectedEndDate, format: "yyyy-MM-dd"),
+                      fontSize: 14,
+                      hint: "Choose End Date".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                  ],
+                ),
+              ).onTap(() {
+                pickerEndDate();
+              }),
+
+              //按钮组
+              Row(
+                children: [
+                  MyButton(
+                    onPressed: () {
+                      //只是Reset当前的弹窗筛选选项
+                      widget.selectedStartDate = null;
+                      widget.selectedEndDate = null;
+                      widget.selectedStatusId = null;
+                      widget.selectedDepartmentId = null;
+
+                      setState(() {
+                        selectedStartDate = null;
+                        selectedEndDate = null;
+                        selectedStatusId = null;
+                        selectedDepartmentId = null;
+                      });
+                    },
+                    text: "Reset".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#FFBB1B"),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 36,
+                  ).expanded(),
+                  SizedBox(width: 15),
+                  MyButton(
+                    onPressed: () {
+                      onCancel();
+                      widget.onFilterAction?.call(selectedStartDate, selectedEndDate, selectedStatusId, selectedDepartmentId);
+                    },
+                    text: "Filter".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#0AC074"),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 36,
+                  ).expanded(),
+                ],
+              ).marginOnly(top: 20),
+            ],
+          ),
+        ),
+        Center(child: MyAssetImage(Assets.baseServiceDialogDeleteIcon, width: 26.5, height: 26.5).marginOnly(top: 35)).onTap(() {
+          onCancel();
+        }),
+      ],
+    );
+  }
+
+  //取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+
+  /// 筛选开始日期
+  void pickerStartDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedStartDate,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedStartDate = date;
+        });
+      },
+      title: "Start Date".tr,
+    );
+  }
+
+  /// 筛选结束日期
+  void pickerEndDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedEndDate ?? selectedStartDate,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedEndDate = date;
+        });
+      },
+      title: "End Date".tr,
+    );
+  }
+
+  /// 筛选部门
+  void pickerOutlet() {
+    int selectedDepartmentIndex;
+    if (selectedDepartmentId == null) {
+      selectedDepartmentIndex = 0;
+    } else {
+      selectedDepartmentIndex = (widget.optionResult.departmentList?.isEmpty == true ? widget.optionResult.outletList : widget.optionResult.departmentList)!
+          .indexWhere((department) => department.value.toString() == selectedDepartmentId);
+    }
+
+    if (selectedDepartmentIndex < 0) {
+      selectedDepartmentIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: (widget.optionResult.departmentList?.isEmpty == true ? widget.optionResult.outletList : widget.optionResult.departmentList)!.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedDepartmentIndex,
+      onPickerChanged: (_, index) {
+        setState(() {
+          selectedDepartmentId = (widget.optionResult.departmentList?.isEmpty == true ? widget.optionResult.outletList : widget.optionResult.departmentList)![index].value!.toString();
+        });
+      },
+    );
+  }
+
+  /// 筛选状态
+  void pickerStatus() {
+    int selectedStatusIndex;
+    if (selectedStatusId == null) {
+      selectedStatusIndex = 0;
+    } else {
+      selectedStatusIndex = widget.optionResult.statusList!.indexWhere((department) => department.value.toString() == selectedStatusId);
+    }
+
+    if (selectedStatusIndex < 0) {
+      selectedStatusIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: widget.optionResult.statusList!.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedStatusIndex,
+      onPickerChanged: (_, index) {
+        setState(() {
+          selectedStatusId = widget.optionResult.statusList![index].value!.toString();
+        });
+      },
+    );
+  }
+}

+ 269 - 0
packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_item.dart

@@ -0,0 +1,269 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/labour_request_list_entity.dart';
+import 'package:domain/entity/response/labour_request_s_g_list_entity.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:plugin_basic/basic_export.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_view.dart';
+
+/*
+ * 用工请求的主页面列表Item
+ */
+class LabourRequestItem extends StatelessWidget {
+  final int index;
+  final LabourRequestSGListRows item;
+  final VoidCallback? onDeleteAction;
+  final VoidCallback? onDetailAction;
+  final VoidCallback? onEditAction;
+
+  LabourRequestItem({
+    required this.index,
+    required this.item,
+    this.onDeleteAction,
+    this.onDetailAction,
+    this.onEditAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          //工作标题
+          MyTextView(
+            item.jobTitle ?? "-",
+            isFontMedium: true,
+            textColor: ColorConstants.textYellowFFBB1B,
+            fontSize: 14,
+            textDecoration: TextDecoration.underline,
+            decorationColor: ColorConstants.textYellowFFBB1B,
+            // 可选,设置下划线的颜色
+            decorationThickness: 2.0,
+            // 可选,设置下划线的粗细
+            decorationStyle: TextDecorationStyle.solid, // 可选,设置下划线的样式
+          ),
+
+          // 部门
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Outlet:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //部门
+              MyTextView(
+                item.outletName ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 工作日期时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Datetime:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //日期时间
+              MyTextView(
+                 "${item.jobDate} (${item.startTime} - ${item.endTime})",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 人数
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "No. of Staff:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //人数
+              MyTextView(
+                item.needNum.toString(),
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 状态
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Status:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //状态
+              MyTextView(
+                item.statusShow == null ? "" : item.statusShow!.tr,
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: "Approved" == item.statusShow
+                    ? ColorConstants.textGreen05DC82
+                    : "Rejected" == item.statusShow
+                        ? ColorConstants.textRedFF6262
+                        : "Recall" == item.statusShow
+                            ? ColorConstants.textYellowFFBB1B
+                            : ColorConstants.textBlue06D9FF,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // // 发布状态
+          // Row(
+          //   mainAxisSize: MainAxisSize.max,
+          //   crossAxisAlignment: CrossAxisAlignment.center,
+          //   children: [
+          //     MyTextView(
+          //       "Publish Status:".tr,
+          //       isFontRegular: true,
+          //       textColor: ColorConstants.textGrayAECAE5,
+          //       fontSize: 14,
+          //     ),
+          //
+          //     //发布状态
+          //     MyTextView(
+          //       item.publishStatus ? "Published".tr : "Unpublished".tr,
+          //       marginLeft: 5,
+          //       isFontRegular: true,
+          //       textColor: Colors.white,
+          //       fontSize: 14,
+          //     ).expanded(),
+          //   ],
+          // ).marginOnly(top: 15),
+
+          // 创建时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Created At:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //发布状态
+              MyTextView(
+                item.createdAt ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          //按钮组
+          Visibility(
+            visible: item.actionList?.isNotEmpty ?? false,
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              mainAxisAlignment: MainAxisAlignment.end,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                //详情按钮
+                Visibility(
+                  visible: item.actionList?.contains("detail") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onDetailAction?.call();
+                    },
+                    text: "Detail".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor(
+                      "#56AAFF",
+                    ),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
+                //Delete按钮
+                Visibility(
+                  visible: item.actionList?.contains("delete") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onDeleteAction?.call();
+                    },
+                    text: "Delete".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: ColorConstants.textRedFF6262,
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
+                //Edit按钮
+                Visibility(
+                  visible: item.actionList?.contains("edit") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onEditAction?.call();
+                    },
+                    text: "Edit".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#FFBB1B"),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
+              ],
+            ).marginOnly(top: 18, bottom: 2),
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 300 - 0
packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_controller.dart

@@ -0,0 +1,300 @@
+import 'package:domain/entity/response/labour_request_s_g_list_entity.dart';
+import 'package:domain/repository/labour_sg_repository.dart';
+
+import '../labour_request_add/labour_request_add_page.dart';
+import 'package:domain/entity/response/labour_request_index_entity.dart';
+import 'package:get/get.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/dialog/app_default_dialog.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../labour_request_edit/labour_request_edit_page.dart';
+import 'labour_request_filter.dart';
+import 'labour_request_list_state.dart';
+
+class LabourRequestListController extends GetxController with DioCancelableMixin {
+  final LabourSGRepository _labourRepository = Get.find();
+  final LabourRequestListState state = LabourRequestListState();
+
+  var _curPage = 1;
+  var _needShowPlaceholder = true;
+
+  //页面PlaceHolder的展示
+  LoadState loadingState = LoadState.State_Success;
+  String? errorMessage;
+
+  //刷新页面状态
+  void changeLoadingState(LoadState state) {
+    loadingState = state;
+    update();
+  }
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,
+    controlFinishLoad: true,
+  );
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchLabourRequestList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchLabourRequestList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchLabourRequestList();
+  }
+
+  /// 获取列表数据
+  Future fetchLabourRequestList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    // 并发执行两个请求
+    var futures = [
+      _labourRepository.fetchLabourRequestSGList(
+        state.keyword,
+        DateTimeUtils.formatDate(state.selectedStartDate, format: "yyyy-MM-dd"),
+        DateTimeUtils.formatDate(state.selectedEndDate, format: "yyyy-MM-dd"),
+        state.selectedStatusId,
+        state.selectedDepartmentId,
+        curPage: _curPage,
+        cancelToken: cancelToken,
+      ),
+      state.indexOptions == null
+          ? _labourRepository.fetchLabourRequestSGIndex(
+              cancelToken: cancelToken,
+            )
+          : Future(() => HttpResult(isSuccess: true).convert(data: state.indexOptions!)),
+    ];
+
+    //拿到结果
+    var results = await Future.wait(futures);
+    var listResult = results[0] as HttpResult<LabourRequestSGListEntity>;
+    var optionResult = results[1] as HttpResult<LabourRequestIndexEntity>;
+
+    //选项数据
+    if (state.indexOptions == null && optionResult.isSuccess) {
+      state.indexOptions = optionResult.data!;
+    }
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.rows);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<LabourRequestSGListRows>? 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 doSearch(String keyword) {
+    state.keyword = keyword;
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  // 清空搜索条件
+  void resetFiltering() {
+    state.keyword = "";
+    state.searchController.text = "";
+
+    state.selectedStartDate = null;
+    state.selectedEndDate = null;
+    state.selectedStatusId = null;
+    state.selectedDepartmentId = null;
+
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  //展示筛选的弹窗
+  void showFilterDialog() {
+    if (state.indexOptions != null) {
+      DialogEngine.show(
+        widget: LabourRequestFilter(
+          optionResult: state.indexOptions!,
+          selectedStartDate: state.selectedStartDate,
+          selectedEndDate: state.selectedEndDate,
+          selectedStatusId: state.selectedStatusId,
+          selectedDepartmentId: state.selectedDepartmentId,
+          onFilterAction: (startDate, endDate, statusId, departmentId) {
+            state.selectedStartDate = startDate;
+            state.selectedEndDate = endDate;
+            state.selectedStatusId = statusId;
+            state.selectedDepartmentId = departmentId;
+
+            //赋值之后刷新
+            refreshController.callRefresh();
+          },
+        ),
+        position: DialogPosition.top,
+        animType: DialogAnimation.fade,
+      );
+    }
+  }
+
+  /// 根据ID获取Item对象,用于刷新
+  void fetchItemByIdAndRefreshItem(String requestId) async {
+    var result = await _labourRepository.fetchItemByRequestId(
+      requestId,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      var data = result.data;
+      if (data != null && data.rows != null && data.rows!.isNotEmpty) {
+        final requestItem = data.rows![0];
+
+        //找到当前数据中的此 requestId,并替换对象,再刷新
+        var index = state.datas.indexWhere((element) => element.requestId == requestItem.requestId);
+        if (index >= 0) {
+          state.datas[index] = requestItem;
+          update();
+        }
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchLabourRequestList();
+
+    registerEventBus();
+  }
+
+  @override
+  void onClose() {
+    unregisterEventBus();
+    state.datas.clear();
+    super.onClose();
+  }
+
+  // EventBus 的事件接收
+  Subscription? subscribe;
+
+  void registerEventBus() {
+    subscribe = bus.on(AppConstant.eventLabourRequestRefresh, (arg) {
+      var requestId = arg as String;
+      if (Utils.isNotEmpty(requestId)) {
+        fetchItemByIdAndRefreshItem(requestId);
+      } else {
+        refreshController.callRefresh();
+      }
+    });
+  }
+
+  void unregisterEventBus() {
+    bus.off(AppConstant.eventLabourRequestRefresh, subscribe);
+  }
+
+  //跳转到添加页面
+  void gotoAddLabourPage() {
+    LabourRequestAddPage.startInstance((result) {
+      if (result is bool) {
+        //添加成功之后刷新
+        refreshController.callRefresh();
+      }
+    });
+  }
+
+  //去详情页面
+  void gotoDetailPage(LabourRequestSGListRows data) {
+    LabourRequestEditPage.startInstance(2, data.requestId, null);
+  }
+
+  //去编辑页面
+  void gotoEditPage(LabourRequestSGListRows data) {
+    LabourRequestEditPage.startInstance(1, data.requestId, (result) {
+      if (result != null) {
+        fetchItemByIdAndRefreshItem(data.requestId.toString());
+      }
+    });
+  }
+
+  //删除labourRequest
+  void doDelete(String? requestId, int index) {
+    DialogEngine.show(
+        widget: AppDefaultDialog(
+      title: "Confirmation".tr,
+      message: "Are you sure you want to delete this labour request?".tr,
+      confirmAction: () {
+        _submitDeleteRequest(requestId, index);
+      },
+    ));
+  }
+
+  void _submitDeleteRequest(String? requestId, int index) async {
+    var result = await _labourRepository.deleteLabourRequestSG(requestId, cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      if (state.datas.length <= 1) {
+        refreshController.callRefresh();
+      } else {
+        state.datas.removeAt(index);
+        update();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+}

+ 164 - 0
packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_page.dart

@@ -0,0 +1,164 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:plugin_basic/base/base_state.dart';
+import 'package:plugin_basic/base/base_stateful_page.dart';
+import 'package:plugin_basic/utils/ext_get_nav.dart';
+import 'package:router/path/router_path.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'labour_request_item.dart';
+import 'labour_request_list_controller.dart';
+import 'labour_request_list_state.dart';
+
+/*
+ * 新加坡的用工请求的主页列表
+ */
+class LabourRequestListPage extends BaseStatefulPage<LabourRequestListController> {
+  LabourRequestListPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance() {
+    return Get.start(RouterPath.labourRequestSG);
+  }
+
+  @override
+  LabourRequestListController createRawController() {
+    return LabourRequestListController();
+  }
+
+  @override
+  State<LabourRequestListPage> createState() => _LabourRequestListState();
+}
+
+class _LabourRequestListState extends BaseState<LabourRequestListPage, LabourRequestListController> {
+  late LabourRequestListState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return SafeArea(
+        bottom: true,
+        top: false,
+        child: Container(
+          width: double.infinity,
+          height: double.infinity,
+          padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+          decoration: const BoxDecoration(
+            gradient: LinearGradient(
+              colors: [
+                Color(0xFF091D44),
+                Color(0xFF245A8A),
+                Color(0xFF7F7CEC),
+              ],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            ),
+          ),
+          child: Column(
+            children: [
+              MyAppBar.searchTitleBar(
+                context,
+                value: state.keyword,
+                hintText: 'Title'.tr,
+                controller: state.searchController,
+                onSearch: (keyword) {
+                  controller.doSearch(keyword);
+                },
+                actions: [
+                  //重置按钮
+                  MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      controller.resetFiltering();
+                    },
+                    text: "Reset".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#2BA9F9", opacity: 0.5),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(right: 15),
+
+                  //筛选图标
+                  const MyAssetImage(
+                    Assets.baseServiceTitleBarFilterIcon,
+                    width: 24,
+                    height: 16.5,
+                  ).onTap(() {
+                    FocusScope.of(context).unfocus();
+                    controller.showFilterDialog();
+                  }).marginOnly(right: 15),
+                ],
+              ),
+              // 添加按钮
+              MyButton(
+                type: ClickType.throttle,
+                milliseconds: 500,
+                onPressed: () {
+                  FocusScope.of(context).unfocus();
+                  controller.gotoAddLabourPage();
+                },
+                text: "Create New Job Request".tr,
+                textColor: ColorConstants.white,
+                fontSize: 16,
+                radius: 20,
+                backgroundColor: hexToColor("#FFBB1B"),
+                fontWeight: FontWeight.w500,
+              ).marginSymmetric(horizontal: 15, vertical: 15),
+
+              //底部的列表
+              EasyRefresh(
+                controller: controller.refreshController,
+                onRefresh: controller.onRefresh,
+                onLoad: controller.loadMore,
+                child: LoadStateLayout(
+                  state: controller.loadingState,
+                  errorMessage: controller.errorMessage,
+                  errorRetry: () {
+                    controller.retryRequest();
+                  },
+                  successSliverWidget: [
+                    SliverList(
+                        delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                        return LabourRequestItem(
+                          index: index,
+                          item: state.datas[index],
+                          onDetailAction: () {
+                            controller.gotoDetailPage(state.datas[index]);
+                          },
+                          onDeleteAction: () {
+                            controller.doDelete(state.datas[index].requestId,index);
+                          },
+                          onEditAction: () {
+                            controller.gotoEditPage(state.datas[index]);
+                          },
+
+                        );
+                      },
+                      childCount: state.datas.length,
+                    ))
+                  ],
+                ),
+              ).expanded(),
+            ],
+          ),
+        ),
+      );
+    });
+  }
+}

+ 18 - 0
packages/cpt_labour_sg/lib/modules/labour_request_list/labour_request_list_state.dart

@@ -0,0 +1,18 @@
+import 'package:domain/entity/response/labour_request_index_entity.dart';
+import 'package:domain/entity/response/labour_request_list_entity.dart';
+import 'package:domain/entity/response/labour_request_s_g_list_entity.dart';
+import 'package:flutter/material.dart';
+
+class LabourRequestListState {
+  //筛选条件
+  final TextEditingController searchController = TextEditingController();
+  String keyword = "";
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+  String? selectedStatusId;
+  String? selectedDepartmentId;
+
+  //页面的列表数据
+  List<LabourRequestSGListRows> datas = [];
+  LabourRequestIndexEntity? indexOptions;
+}

+ 3 - 3
packages/cpt_labour_sg/lib/router/labour_sg_service_impl.dart

@@ -1,9 +1,9 @@
 import 'package:cpt_labour_sg/modules/job_list/job_list_page.dart';
 import 'package:cpt_labour_sg/modules/job_title_list/job_title_list_page.dart';
-import 'package:cpt_labour_sg/modules/labour_request/labour_request_page.dart';
 import 'package:plugin_basic/basic_export.dart';
 import 'package:router/componentRouter/labour_sg_service.dart';
-import 'package:shared/utils/log_utils.dart';
+
+import '../modules/labour_request_list/labour_request_list_page.dart';
 
 class LabourSGServiceImpl extends GetxService implements LabourSGService {
   @override
@@ -20,7 +20,7 @@ class LabourSGServiceImpl extends GetxService implements LabourSGService {
 
   @override
   void startLabourRequestPage() {
-    LabourRequestPage.startInstance();
+    LabourRequestListPage.startInstance();
   }
 
   @override

+ 9 - 3
packages/cpt_labour_sg/lib/router/page_router.dart

@@ -2,14 +2,14 @@
 import 'package:cpt_labour_sg/modules/job_template_add/job_template_add_page.dart';
 import 'package:cpt_labour_sg/modules/job_template_list/job_template_list_page.dart';
 import 'package:cpt_labour_sg/modules/job_title_list/job_title_list_page.dart';
-import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:router/path/router_path.dart';
 
 import '../modules/job_list/job_list_page.dart';
 import '../modules/job_list_edit/job_list_edit_page.dart';
-import '../modules/labour_request/labour_request_page.dart';
 import '../modules/labour_request_add/labour_request_add_page.dart';
+import '../modules/labour_request_edit/labour_request_edit_page.dart';
+import '../modules/labour_request_list/labour_request_list_page.dart';
 
 
 class LabourSGPageRouter {
@@ -34,10 +34,16 @@ class LabourSGPageRouter {
       page: () => JobTemplateAddPage(),
     ),
 
+    // 用工的编辑
+    GetPage(
+      name: RouterPath.labourRequestEditSG,
+      page: () => LabourRequestEditPage(),
+    ),
+
     // 用工请求
     GetPage(
       name: RouterPath.labourRequestSG,
-      page: () => LabourRequestPage(),
+      page: () => LabourRequestListPage(),
     ),
 
     // 用工请求添加

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

@@ -188,6 +188,9 @@ class ApiConstants {
   //用工请求的考勤确认(Job List)
   static const apiJobListConfirmSG = "/index.php/api/v1/hotel/job/confirm";
 
+  //新加坡的用工请求删除
+  static const apiLabourRequestDelete = "/index.php/api/v1/hotel/lab-req/destroy";
+
   // =========================== 新加坡工作相关 ↓=========================================
 
   //新加坡工作已申请的选项

+ 2 - 0
packages/cs_domain/lib/entity/response/labour_request_index_entity.dart

@@ -7,6 +7,8 @@ export 'package:domain/generated/json/labour_request_index_entity.g.dart';
 class LabourRequestIndexEntity {
 	@JSONField(name: "department_list")
 	List<LabourRequestIndexDepartmentList>? departmentList = [];
+	@JSONField(name: "outlet_list")
+	List<LabourRequestIndexDepartmentList>? outletList = [];
 	@JSONField(name: "status_list")
 	List<LabourRequestIndexStatusList>? statusList = [];
 

+ 41 - 41
packages/cs_domain/lib/entity/response/labour_request_list_entity.dart

@@ -5,52 +5,52 @@ export 'package:domain/generated/json/labour_request_list_entity.g.dart';
 
 @JsonSerializable()
 class LabourRequestListEntity {
-	int? total = 0;
-	List<LabourRequestListRows>? rows = [];
+  int? total = 0;
+  List<LabourRequestListRows>? rows = [];
 
-	LabourRequestListEntity();
+  LabourRequestListEntity();
 
-	factory LabourRequestListEntity.fromJson(Map<String, dynamic> json) => $LabourRequestListEntityFromJson(json);
+  factory LabourRequestListEntity.fromJson(Map<String, dynamic> json) => $LabourRequestListEntityFromJson(json);
 
-	Map<String, dynamic> toJson() => $LabourRequestListEntityToJson(this);
+  Map<String, dynamic> toJson() => $LabourRequestListEntityToJson(this);
 
-	@override
-	String toString() {
-		return jsonEncode(this);
-	}
+  @override
+  String toString() {
+    return jsonEncode(this);
+  }
 }
 
 @JsonSerializable()
 class LabourRequestListRows {
-	@JSONField(name: "request_id")
-	int requestId = 0;
-	@JSONField(name: "job_title")
-	String? jobTitle;
-	@JSONField(name: "department_name")
-	String? departmentName;
-	@JSONField(name: "job_time")
-	String? jobTime ;
-	@JSONField(name: "need_num")
-	int needNum = 0;
-	@JSONField(name: "co_status")
-	int? coStatus = 0;
-	@JSONField(name: "co_status_show")
-	String? coStatusShow;
-	@JSONField(name: "publish_status")
-	bool publishStatus = false;
-	@JSONField(name: "created_at")
-	String? createdAt;
-	@JSONField(name: "action_list")
-	List<String>? actionList = [];
-
-	LabourRequestListRows();
-
-	factory LabourRequestListRows.fromJson(Map<String, dynamic> json) => $LabourRequestListRowsFromJson(json);
-
-	Map<String, dynamic> toJson() => $LabourRequestListRowsToJson(this);
-
-	@override
-	String toString() {
-		return jsonEncode(this);
-	}
-}
+  @JSONField(name: "request_id")
+  int requestId = 0;
+  @JSONField(name: "job_title")
+  String? jobTitle;
+  @JSONField(name: "department_name")
+  String? departmentName;
+  @JSONField(name: "job_time")
+  String? jobTime;
+  @JSONField(name: "need_num")
+  int needNum = 0;
+  @JSONField(name: "co_status")
+  int? coStatus = 0;
+  @JSONField(name: "co_status_show")
+  String? coStatusShow;
+  @JSONField(name: "publish_status")
+  bool publishStatus = false;
+  @JSONField(name: "created_at")
+  String? createdAt;
+  @JSONField(name: "action_list")
+  List<String>? actionList = [];
+
+  LabourRequestListRows();
+
+  factory LabourRequestListRows.fromJson(Map<String, dynamic> json) => $LabourRequestListRowsFromJson(json);
+
+  Map<String, dynamic> toJson() => $LabourRequestListRowsToJson(this);
+
+  @override
+  String toString() {
+    return jsonEncode(this);
+  }
+}

+ 142 - 0
packages/cs_domain/lib/entity/response/labour_request_s_g_edit_index_entity.dart

@@ -0,0 +1,142 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/labour_request_s_g_edit_index_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/labour_request_s_g_edit_index_entity.g.dart';
+
+@JsonSerializable()
+class LabourRequestSGEditIndexEntity {
+	LabourRequestSGEditIndexJob? job;
+	@JSONField(name: "request_id")
+	String? requestId;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "outlet_id")
+	int? outletId;
+	@JSONField(name: "req_type")
+	int? reqType;
+	@JSONField(name: "start_time")
+	String? startTime;
+	String? remark;
+	@JSONField(name: "end_time")
+	String? endTime;
+	@JSONField(name: "outlet_list")
+	List<LabourRequestSGEditIndexJob> outletList = [];
+	@JSONField(name: "request_type")
+	List<LabourRequestSGEditIndexChecked> requestType = [];
+	@JSONField(name: "limit_list")
+	List<LabourRequestSGEditIndexJob> limitList = [];
+	@JSONField(name: "look_remark")
+	bool? lookRemark;
+
+	LabourRequestSGEditIndexEntity();
+
+	factory LabourRequestSGEditIndexEntity.fromJson(Map<String, dynamic> json) => $LabourRequestSGEditIndexEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGEditIndexEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class LabourRequestSGEditIndexJob {
+	String? id;
+	@JSONField(name: "employer_admin_id")
+	String? employerAdminId;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "need_num")
+	int? needNum;
+	@JSONField(name: "gender_number_limit")
+	int? genderNumberLimit;
+	@JSONField(name: "male_number_limit")
+	int? maleNumberLimit;
+	@JSONField(name: "female_number_limit")
+	int? femaleNumberLimit;
+	@JSONField(name: "job_start")
+	String? jobStart;
+	@JSONField(name: "job_end")
+	String? jobEnd;
+	@JSONField(name: "job_id")
+	int? jobId;
+	@JSONField(name: "remark_id")
+	int? remarkId;
+	String? status;
+	@JSONField(name: "add_time")
+	String? addTime;
+	String? from;
+	@JSONField(name: "reject_reason")
+	dynamic rejectReason;
+	dynamic banquet;
+	@JSONField(name: "hotel_job_id")
+	int? hotelJobId;
+	@JSONField(name: "work_content")
+	String? workContent;
+	@JSONField(name: "crm_contract_position_id")
+	int? crmContractPositionId;
+	@JSONField(name: "rate_type")
+	int? rateType;
+	@JSONField(name: "is_send")
+	int? isSend;
+	@JSONField(name: "request_type")
+	int? requestType;
+	@JSONField(name: "outlet_id")
+	int? outletId;
+	@JSONField(name: "outlet_name")
+	String? outletName;
+	@JSONField(name: "job_title_id")
+	int? jobTitleId;
+	@JSONField(name: "agency_rate")
+	String? agencyRate;
+	@JSONField(name: "hotel_remark")
+	dynamic hotelRemark;
+
+	LabourRequestSGEditIndexJob();
+
+	factory LabourRequestSGEditIndexJob.fromJson(Map<String, dynamic> json) => $LabourRequestSGEditIndexJobFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGEditIndexJobToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class LabourRequestSGEditSelected {
+	String? value;
+	String? txt;
+	String? selected;
+
+	LabourRequestSGEditSelected();
+
+	factory LabourRequestSGEditSelected.fromJson(Map<String, dynamic> json) => $LabourRequestSGEditSelectedFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGEditSelectedToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class LabourRequestSGEditIndexChecked {
+	String? value;
+	String? txt;
+	String? checked;
+
+	LabourRequestSGEditIndexChecked();
+
+	factory LabourRequestSGEditIndexChecked.fromJson(Map<String, dynamic> json) => $LabourRequestSGEditIndexCheckedFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGEditIndexCheckedToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 57 - 0
packages/cs_domain/lib/entity/response/labour_request_s_g_list_entity.dart

@@ -0,0 +1,57 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/labour_request_s_g_list_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/labour_request_s_g_list_entity.g.dart';
+
+@JsonSerializable()
+class LabourRequestSGListEntity {
+	int? total;
+	List<LabourRequestSGListRows>? rows = [];
+
+	LabourRequestSGListEntity();
+
+	factory LabourRequestSGListEntity.fromJson(Map<String, dynamic> json) => $LabourRequestSGListEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGListEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class LabourRequestSGListRows {
+	@JSONField(name: "request_id")
+	String? requestId;
+	@JSONField(name: "outlet_name")
+	String? outletName;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "need_num")
+	int? needNum;
+	@JSONField(name: "job_date")
+	String? jobDate;
+	@JSONField(name: "start_time")
+	String? startTime;
+	@JSONField(name: "end_time")
+	String? endTime;
+	String? status;
+	@JSONField(name: "status_show")
+	String? statusShow;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	@JSONField(name: "action_list")
+	List<String> actionList = [];
+
+	LabourRequestSGListRows();
+
+	factory LabourRequestSGListRows.fromJson(Map<String, dynamic> json) => $LabourRequestSGListRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $LabourRequestSGListRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

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

@@ -40,7 +40,9 @@ import 'package:domain/entity/response/labour_request_edit_index_entity.dart';
 import 'package:domain/entity/response/labour_request_index_entity.dart';
 import 'package:domain/entity/response/labour_request_list_entity.dart';
 import 'package:domain/entity/response/labour_request_s_g_add_index_entity.dart';
+import 'package:domain/entity/response/labour_request_s_g_edit_index_entity.dart';
 import 'package:domain/entity/response/labour_request_s_g_entity.dart';
+import 'package:domain/entity/response/labour_request_s_g_list_entity.dart';
 import 'package:domain/entity/response/labour_request_work_flow_entity.dart';
 import 'package:domain/entity/response/labour_review_list_entity.dart';
 import 'package:domain/entity/response/labour_review_status_entity.dart';
@@ -428,12 +430,30 @@ class JsonConvert {
     if (<LabourRequestSGAddIndexOption>[] is M) {
       return data.map<LabourRequestSGAddIndexOption>((Map<String, dynamic> e) => LabourRequestSGAddIndexOption.fromJson(e)).toList() as M;
     }
+    if (<LabourRequestSGEditIndexEntity>[] is M) {
+      return data.map<LabourRequestSGEditIndexEntity>((Map<String, dynamic> e) => LabourRequestSGEditIndexEntity.fromJson(e)).toList() as M;
+    }
+    if (<LabourRequestSGEditIndexJob>[] is M) {
+      return data.map<LabourRequestSGEditIndexJob>((Map<String, dynamic> e) => LabourRequestSGEditIndexJob.fromJson(e)).toList() as M;
+    }
+    if (<LabourRequestSGEditSelected>[] is M) {
+      return data.map<LabourRequestSGEditSelected>((Map<String, dynamic> e) => LabourRequestSGEditSelected.fromJson(e)).toList() as M;
+    }
+    if (<LabourRequestSGEditIndexChecked>[] is M) {
+      return data.map<LabourRequestSGEditIndexChecked>((Map<String, dynamic> e) => LabourRequestSGEditIndexChecked.fromJson(e)).toList() as M;
+    }
     if (<LabourRequestSGEntity>[] is M) {
       return data.map<LabourRequestSGEntity>((Map<String, dynamic> e) => LabourRequestSGEntity.fromJson(e)).toList() as M;
     }
     if (<LabourRequestSGCountList>[] is M) {
       return data.map<LabourRequestSGCountList>((Map<String, dynamic> e) => LabourRequestSGCountList.fromJson(e)).toList() as M;
     }
+    if (<LabourRequestSGListEntity>[] is M) {
+      return data.map<LabourRequestSGListEntity>((Map<String, dynamic> e) => LabourRequestSGListEntity.fromJson(e)).toList() as M;
+    }
+    if (<LabourRequestSGListRows>[] is M) {
+      return data.map<LabourRequestSGListRows>((Map<String, dynamic> e) => LabourRequestSGListRows.fromJson(e)).toList() as M;
+    }
     if (<LabourRequestWorkFlowEntity>[] is M) {
       return data.map<LabourRequestWorkFlowEntity>((Map<String, dynamic> e) => LabourRequestWorkFlowEntity.fromJson(e)).toList() as M;
     }
@@ -633,8 +653,14 @@ class JsonConvertClassCollection {
     (LabourRequestListRows).toString(): LabourRequestListRows.fromJson,
     (LabourRequestSGAddIndexEntity).toString(): LabourRequestSGAddIndexEntity.fromJson,
     (LabourRequestSGAddIndexOption).toString(): LabourRequestSGAddIndexOption.fromJson,
+    (LabourRequestSGEditIndexEntity).toString(): LabourRequestSGEditIndexEntity.fromJson,
+    (LabourRequestSGEditIndexJob).toString(): LabourRequestSGEditIndexJob.fromJson,
+    (LabourRequestSGEditSelected).toString(): LabourRequestSGEditSelected.fromJson,
+    (LabourRequestSGEditIndexChecked).toString(): LabourRequestSGEditIndexChecked.fromJson,
     (LabourRequestSGEntity).toString(): LabourRequestSGEntity.fromJson,
     (LabourRequestSGCountList).toString(): LabourRequestSGCountList.fromJson,
+    (LabourRequestSGListEntity).toString(): LabourRequestSGListEntity.fromJson,
+    (LabourRequestSGListRows).toString(): LabourRequestSGListRows.fromJson,
     (LabourRequestWorkFlowEntity).toString(): LabourRequestWorkFlowEntity.fromJson,
     (LabourRequestWorkFlowRecords).toString(): LabourRequestWorkFlowRecords.fromJson,
     (LabourReviewListEntity).toString(): LabourReviewListEntity.fromJson,

+ 8 - 0
packages/cs_domain/lib/generated/json/labour_request_index_entity.g.dart

@@ -8,6 +8,11 @@ LabourRequestIndexEntity $LabourRequestIndexEntityFromJson(Map<String, dynamic>
   if (departmentList != null) {
     labourRequestIndexEntity.departmentList = departmentList;
   }
+  final List<LabourRequestIndexDepartmentList>? outletList = (json['outlet_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<LabourRequestIndexDepartmentList>(e) as LabourRequestIndexDepartmentList).toList();
+  if (outletList != null) {
+    labourRequestIndexEntity.outletList = outletList;
+  }
   final List<LabourRequestIndexStatusList>? statusList = (json['status_list'] as List<dynamic>?)?.map(
           (e) => jsonConvert.convert<LabourRequestIndexStatusList>(e) as LabourRequestIndexStatusList).toList();
   if (statusList != null) {
@@ -19,6 +24,7 @@ LabourRequestIndexEntity $LabourRequestIndexEntityFromJson(Map<String, dynamic>
 Map<String, dynamic> $LabourRequestIndexEntityToJson(LabourRequestIndexEntity entity) {
   final Map<String, dynamic> data = <String, dynamic>{};
   data['department_list'] = entity.departmentList?.map((v) => v.toJson()).toList();
+  data['outlet_list'] = entity.outletList?.map((v) => v.toJson()).toList();
   data['status_list'] = entity.statusList?.map((v) => v.toJson()).toList();
   return data;
 }
@@ -26,10 +32,12 @@ Map<String, dynamic> $LabourRequestIndexEntityToJson(LabourRequestIndexEntity en
 extension LabourRequestIndexEntityExtension on LabourRequestIndexEntity {
   LabourRequestIndexEntity copyWith({
     List<LabourRequestIndexDepartmentList>? departmentList,
+    List<LabourRequestIndexDepartmentList>? outletList,
     List<LabourRequestIndexStatusList>? statusList,
   }) {
     return LabourRequestIndexEntity()
       ..departmentList = departmentList ?? this.departmentList
+      ..outletList = outletList ?? this.outletList
       ..statusList = statusList ?? this.statusList;
   }
 }

+ 388 - 0
packages/cs_domain/lib/generated/json/labour_request_s_g_edit_index_entity.g.dart

@@ -0,0 +1,388 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/labour_request_s_g_edit_index_entity.dart';
+
+LabourRequestSGEditIndexEntity $LabourRequestSGEditIndexEntityFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGEditIndexEntity labourRequestSGEditIndexEntity = LabourRequestSGEditIndexEntity();
+  final LabourRequestSGEditIndexJob? job = jsonConvert.convert<LabourRequestSGEditIndexJob>(json['job']);
+  if (job != null) {
+    labourRequestSGEditIndexEntity.job = job;
+  }
+  final String? requestId = jsonConvert.convert<String>(json['request_id']);
+  if (requestId != null) {
+    labourRequestSGEditIndexEntity.requestId = requestId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    labourRequestSGEditIndexEntity.jobTitle = jobTitle;
+  }
+  final int? outletId = jsonConvert.convert<int>(json['outlet_id']);
+  if (outletId != null) {
+    labourRequestSGEditIndexEntity.outletId = outletId;
+  }
+  final int? reqType = jsonConvert.convert<int>(json['req_type']);
+  if (reqType != null) {
+    labourRequestSGEditIndexEntity.reqType = reqType;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    labourRequestSGEditIndexEntity.startTime = startTime;
+  }
+  final String? remark = jsonConvert.convert<String>(json['remark']);
+  if (remark != null) {
+    labourRequestSGEditIndexEntity.remark = remark;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    labourRequestSGEditIndexEntity.endTime = endTime;
+  }
+  final List<LabourRequestSGEditIndexJob>? outletList = (json['outlet_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<LabourRequestSGEditIndexJob>(e) as LabourRequestSGEditIndexJob).toList();
+  if (outletList != null) {
+    labourRequestSGEditIndexEntity.outletList = outletList;
+  }
+  final List<LabourRequestSGEditIndexChecked>? requestType = (json['request_type'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<LabourRequestSGEditIndexChecked>(e) as LabourRequestSGEditIndexChecked).toList();
+  if (requestType != null) {
+    labourRequestSGEditIndexEntity.requestType = requestType;
+  }
+  final List<LabourRequestSGEditIndexJob>? limitList = (json['limit_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<LabourRequestSGEditIndexJob>(e) as LabourRequestSGEditIndexJob).toList();
+  if (limitList != null) {
+    labourRequestSGEditIndexEntity.limitList = limitList;
+  }
+  final bool? lookRemark = jsonConvert.convert<bool>(json['look_remark']);
+  if (lookRemark != null) {
+    labourRequestSGEditIndexEntity.lookRemark = lookRemark;
+  }
+  return labourRequestSGEditIndexEntity;
+}
+
+Map<String, dynamic> $LabourRequestSGEditIndexEntityToJson(LabourRequestSGEditIndexEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['job'] = entity.job?.toJson();
+  data['request_id'] = entity.requestId;
+  data['job_title'] = entity.jobTitle;
+  data['outlet_id'] = entity.outletId;
+  data['req_type'] = entity.reqType;
+  data['start_time'] = entity.startTime;
+  data['remark'] = entity.remark;
+  data['end_time'] = entity.endTime;
+  data['outlet_list'] = entity.outletList.map((v) => v.toJson()).toList();
+  data['request_type'] = entity.requestType.map((v) => v.toJson()).toList();
+  data['limit_list'] = entity.limitList.map((v) => v.toJson()).toList();
+  data['look_remark'] = entity.lookRemark;
+  return data;
+}
+
+extension LabourRequestSGEditIndexEntityExtension on LabourRequestSGEditIndexEntity {
+  LabourRequestSGEditIndexEntity copyWith({
+    LabourRequestSGEditIndexJob? job,
+    String? requestId,
+    String? jobTitle,
+    int? outletId,
+    int? reqType,
+    String? startTime,
+    String? remark,
+    String? endTime,
+    List<LabourRequestSGEditIndexJob>? outletList,
+    List<LabourRequestSGEditIndexChecked>? requestType,
+    List<LabourRequestSGEditIndexJob>? limitList,
+    bool? lookRemark,
+  }) {
+    return LabourRequestSGEditIndexEntity()
+      ..job = job ?? this.job
+      ..requestId = requestId ?? this.requestId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..outletId = outletId ?? this.outletId
+      ..reqType = reqType ?? this.reqType
+      ..startTime = startTime ?? this.startTime
+      ..remark = remark ?? this.remark
+      ..endTime = endTime ?? this.endTime
+      ..outletList = outletList ?? this.outletList
+      ..requestType = requestType ?? this.requestType
+      ..limitList = limitList ?? this.limitList
+      ..lookRemark = lookRemark ?? this.lookRemark;
+  }
+}
+
+LabourRequestSGEditIndexJob $LabourRequestSGEditIndexJobFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGEditIndexJob labourRequestSGEditIndexJob = LabourRequestSGEditIndexJob();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    labourRequestSGEditIndexJob.id = id;
+  }
+  final String? employerAdminId = jsonConvert.convert<String>(json['employer_admin_id']);
+  if (employerAdminId != null) {
+    labourRequestSGEditIndexJob.employerAdminId = employerAdminId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    labourRequestSGEditIndexJob.jobTitle = jobTitle;
+  }
+  final int? needNum = jsonConvert.convert<int>(json['need_num']);
+  if (needNum != null) {
+    labourRequestSGEditIndexJob.needNum = needNum;
+  }
+  final int? genderNumberLimit = jsonConvert.convert<int>(json['gender_number_limit']);
+  if (genderNumberLimit != null) {
+    labourRequestSGEditIndexJob.genderNumberLimit = genderNumberLimit;
+  }
+  final int? maleNumberLimit = jsonConvert.convert<int>(json['male_number_limit']);
+  if (maleNumberLimit != null) {
+    labourRequestSGEditIndexJob.maleNumberLimit = maleNumberLimit;
+  }
+  final int? femaleNumberLimit = jsonConvert.convert<int>(json['female_number_limit']);
+  if (femaleNumberLimit != null) {
+    labourRequestSGEditIndexJob.femaleNumberLimit = femaleNumberLimit;
+  }
+  final String? jobStart = jsonConvert.convert<String>(json['job_start']);
+  if (jobStart != null) {
+    labourRequestSGEditIndexJob.jobStart = jobStart;
+  }
+  final String? jobEnd = jsonConvert.convert<String>(json['job_end']);
+  if (jobEnd != null) {
+    labourRequestSGEditIndexJob.jobEnd = jobEnd;
+  }
+  final int? jobId = jsonConvert.convert<int>(json['job_id']);
+  if (jobId != null) {
+    labourRequestSGEditIndexJob.jobId = jobId;
+  }
+  final int? remarkId = jsonConvert.convert<int>(json['remark_id']);
+  if (remarkId != null) {
+    labourRequestSGEditIndexJob.remarkId = remarkId;
+  }
+  final String? status = jsonConvert.convert<String>(json['status']);
+  if (status != null) {
+    labourRequestSGEditIndexJob.status = status;
+  }
+  final String? addTime = jsonConvert.convert<String>(json['add_time']);
+  if (addTime != null) {
+    labourRequestSGEditIndexJob.addTime = addTime;
+  }
+  final String? from = jsonConvert.convert<String>(json['from']);
+  if (from != null) {
+    labourRequestSGEditIndexJob.from = from;
+  }
+  final dynamic rejectReason = json['reject_reason'];
+  if (rejectReason != null) {
+    labourRequestSGEditIndexJob.rejectReason = rejectReason;
+  }
+  final dynamic banquet = json['banquet'];
+  if (banquet != null) {
+    labourRequestSGEditIndexJob.banquet = banquet;
+  }
+  final int? hotelJobId = jsonConvert.convert<int>(json['hotel_job_id']);
+  if (hotelJobId != null) {
+    labourRequestSGEditIndexJob.hotelJobId = hotelJobId;
+  }
+  final String? workContent = jsonConvert.convert<String>(json['work_content']);
+  if (workContent != null) {
+    labourRequestSGEditIndexJob.workContent = workContent;
+  }
+  final int? crmContractPositionId = jsonConvert.convert<int>(json['crm_contract_position_id']);
+  if (crmContractPositionId != null) {
+    labourRequestSGEditIndexJob.crmContractPositionId = crmContractPositionId;
+  }
+  final int? rateType = jsonConvert.convert<int>(json['rate_type']);
+  if (rateType != null) {
+    labourRequestSGEditIndexJob.rateType = rateType;
+  }
+  final int? isSend = jsonConvert.convert<int>(json['is_send']);
+  if (isSend != null) {
+    labourRequestSGEditIndexJob.isSend = isSend;
+  }
+  final int? requestType = jsonConvert.convert<int>(json['request_type']);
+  if (requestType != null) {
+    labourRequestSGEditIndexJob.requestType = requestType;
+  }
+  final int? outletId = jsonConvert.convert<int>(json['outlet_id']);
+  if (outletId != null) {
+    labourRequestSGEditIndexJob.outletId = outletId;
+  }
+  final String? outletName = jsonConvert.convert<String>(json['outlet_name']);
+  if (outletName != null) {
+    labourRequestSGEditIndexJob.outletName = outletName;
+  }
+  final int? jobTitleId = jsonConvert.convert<int>(json['job_title_id']);
+  if (jobTitleId != null) {
+    labourRequestSGEditIndexJob.jobTitleId = jobTitleId;
+  }
+  final String? agencyRate = jsonConvert.convert<String>(json['agency_rate']);
+  if (agencyRate != null) {
+    labourRequestSGEditIndexJob.agencyRate = agencyRate;
+  }
+  final dynamic hotelRemark = json['hotel_remark'];
+  if (hotelRemark != null) {
+    labourRequestSGEditIndexJob.hotelRemark = hotelRemark;
+  }
+  return labourRequestSGEditIndexJob;
+}
+
+Map<String, dynamic> $LabourRequestSGEditIndexJobToJson(LabourRequestSGEditIndexJob entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['employer_admin_id'] = entity.employerAdminId;
+  data['job_title'] = entity.jobTitle;
+  data['need_num'] = entity.needNum;
+  data['gender_number_limit'] = entity.genderNumberLimit;
+  data['male_number_limit'] = entity.maleNumberLimit;
+  data['female_number_limit'] = entity.femaleNumberLimit;
+  data['job_start'] = entity.jobStart;
+  data['job_end'] = entity.jobEnd;
+  data['job_id'] = entity.jobId;
+  data['remark_id'] = entity.remarkId;
+  data['status'] = entity.status;
+  data['add_time'] = entity.addTime;
+  data['from'] = entity.from;
+  data['reject_reason'] = entity.rejectReason;
+  data['banquet'] = entity.banquet;
+  data['hotel_job_id'] = entity.hotelJobId;
+  data['work_content'] = entity.workContent;
+  data['crm_contract_position_id'] = entity.crmContractPositionId;
+  data['rate_type'] = entity.rateType;
+  data['is_send'] = entity.isSend;
+  data['request_type'] = entity.requestType;
+  data['outlet_id'] = entity.outletId;
+  data['outlet_name'] = entity.outletName;
+  data['job_title_id'] = entity.jobTitleId;
+  data['agency_rate'] = entity.agencyRate;
+  data['hotel_remark'] = entity.hotelRemark;
+  return data;
+}
+
+extension LabourRequestSGEditIndexJobExtension on LabourRequestSGEditIndexJob {
+  LabourRequestSGEditIndexJob copyWith({
+    String? id,
+    String? employerAdminId,
+    String? jobTitle,
+    int? needNum,
+    int? genderNumberLimit,
+    int? maleNumberLimit,
+    int? femaleNumberLimit,
+    String? jobStart,
+    String? jobEnd,
+    int? jobId,
+    int? remarkId,
+    String? status,
+    String? addTime,
+    String? from,
+    dynamic rejectReason,
+    dynamic banquet,
+    int? hotelJobId,
+    String? workContent,
+    int? crmContractPositionId,
+    int? rateType,
+    int? isSend,
+    int? requestType,
+    int? outletId,
+    String? outletName,
+    int? jobTitleId,
+    String? agencyRate,
+    dynamic hotelRemark,
+  }) {
+    return LabourRequestSGEditIndexJob()
+      ..id = id ?? this.id
+      ..employerAdminId = employerAdminId ?? this.employerAdminId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..needNum = needNum ?? this.needNum
+      ..genderNumberLimit = genderNumberLimit ?? this.genderNumberLimit
+      ..maleNumberLimit = maleNumberLimit ?? this.maleNumberLimit
+      ..femaleNumberLimit = femaleNumberLimit ?? this.femaleNumberLimit
+      ..jobStart = jobStart ?? this.jobStart
+      ..jobEnd = jobEnd ?? this.jobEnd
+      ..jobId = jobId ?? this.jobId
+      ..remarkId = remarkId ?? this.remarkId
+      ..status = status ?? this.status
+      ..addTime = addTime ?? this.addTime
+      ..from = from ?? this.from
+      ..rejectReason = rejectReason ?? this.rejectReason
+      ..banquet = banquet ?? this.banquet
+      ..hotelJobId = hotelJobId ?? this.hotelJobId
+      ..workContent = workContent ?? this.workContent
+      ..crmContractPositionId = crmContractPositionId ?? this.crmContractPositionId
+      ..rateType = rateType ?? this.rateType
+      ..isSend = isSend ?? this.isSend
+      ..requestType = requestType ?? this.requestType
+      ..outletId = outletId ?? this.outletId
+      ..outletName = outletName ?? this.outletName
+      ..jobTitleId = jobTitleId ?? this.jobTitleId
+      ..agencyRate = agencyRate ?? this.agencyRate
+      ..hotelRemark = hotelRemark ?? this.hotelRemark;
+  }
+}
+
+LabourRequestSGEditSelected $LabourRequestSGEditSelectedFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGEditSelected labourRequestSGEditSelected = LabourRequestSGEditSelected();
+  final String? value = jsonConvert.convert<String>(json['value']);
+  if (value != null) {
+    labourRequestSGEditSelected.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    labourRequestSGEditSelected.txt = txt;
+  }
+  final String? selected = jsonConvert.convert<String>(json['selected']);
+  if (selected != null) {
+    labourRequestSGEditSelected.selected = selected;
+  }
+  return labourRequestSGEditSelected;
+}
+
+Map<String, dynamic> $LabourRequestSGEditSelectedToJson(LabourRequestSGEditSelected entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['selected'] = entity.selected;
+  return data;
+}
+
+extension LabourRequestSGEditSelectedExtension on LabourRequestSGEditSelected {
+  LabourRequestSGEditSelected copyWith({
+    String? value,
+    String? txt,
+    String? selected,
+  }) {
+    return LabourRequestSGEditSelected()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..selected = selected ?? this.selected;
+  }
+}
+
+LabourRequestSGEditIndexChecked $LabourRequestSGEditIndexCheckedFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGEditIndexChecked labourRequestSGEditIndexChecked = LabourRequestSGEditIndexChecked();
+  final String? value = jsonConvert.convert<String>(json['value']);
+  if (value != null) {
+    labourRequestSGEditIndexChecked.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    labourRequestSGEditIndexChecked.txt = txt;
+  }
+  final String? checked = jsonConvert.convert<String>(json['checked']);
+  if (checked != null) {
+    labourRequestSGEditIndexChecked.checked = checked;
+  }
+  return labourRequestSGEditIndexChecked;
+}
+
+Map<String, dynamic> $LabourRequestSGEditIndexCheckedToJson(LabourRequestSGEditIndexChecked entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['checked'] = entity.checked;
+  return data;
+}
+
+extension LabourRequestSGEditIndexCheckedExtension on LabourRequestSGEditIndexChecked {
+  LabourRequestSGEditIndexChecked copyWith({
+    String? value,
+    String? txt,
+    String? checked,
+  }) {
+    return LabourRequestSGEditIndexChecked()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..checked = checked ?? this.checked;
+  }
+}

+ 129 - 0
packages/cs_domain/lib/generated/json/labour_request_s_g_list_entity.g.dart

@@ -0,0 +1,129 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/labour_request_s_g_list_entity.dart';
+
+LabourRequestSGListEntity $LabourRequestSGListEntityFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGListEntity labourRequestSGListEntity = LabourRequestSGListEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    labourRequestSGListEntity.total = total;
+  }
+  final List<LabourRequestSGListRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<LabourRequestSGListRows>(e) as LabourRequestSGListRows).toList();
+  if (rows != null) {
+    labourRequestSGListEntity.rows = rows;
+  }
+  return labourRequestSGListEntity;
+}
+
+Map<String, dynamic> $LabourRequestSGListEntityToJson(LabourRequestSGListEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension LabourRequestSGListEntityExtension on LabourRequestSGListEntity {
+  LabourRequestSGListEntity copyWith({
+    int? total,
+    List<LabourRequestSGListRows>? rows,
+  }) {
+    return LabourRequestSGListEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+LabourRequestSGListRows $LabourRequestSGListRowsFromJson(Map<String, dynamic> json) {
+  final LabourRequestSGListRows labourRequestSGListRows = LabourRequestSGListRows();
+  final String? requestId = jsonConvert.convert<String>(json['request_id']);
+  if (requestId != null) {
+    labourRequestSGListRows.requestId = requestId;
+  }
+  final String? outletName = jsonConvert.convert<String>(json['outlet_name']);
+  if (outletName != null) {
+    labourRequestSGListRows.outletName = outletName;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    labourRequestSGListRows.jobTitle = jobTitle;
+  }
+  final int? needNum = jsonConvert.convert<int>(json['need_num']);
+  if (needNum != null) {
+    labourRequestSGListRows.needNum = needNum;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    labourRequestSGListRows.jobDate = jobDate;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    labourRequestSGListRows.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    labourRequestSGListRows.endTime = endTime;
+  }
+  final String? status = jsonConvert.convert<String>(json['status']);
+  if (status != null) {
+    labourRequestSGListRows.status = status;
+  }
+  final String? statusShow = jsonConvert.convert<String>(json['status_show']);
+  if (statusShow != null) {
+    labourRequestSGListRows.statusShow = statusShow;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    labourRequestSGListRows.createdAt = createdAt;
+  }
+  final List<String>? actionList = (json['action_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (actionList != null) {
+    labourRequestSGListRows.actionList = actionList;
+  }
+  return labourRequestSGListRows;
+}
+
+Map<String, dynamic> $LabourRequestSGListRowsToJson(LabourRequestSGListRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['request_id'] = entity.requestId;
+  data['outlet_name'] = entity.outletName;
+  data['job_title'] = entity.jobTitle;
+  data['need_num'] = entity.needNum;
+  data['job_date'] = entity.jobDate;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['status'] = entity.status;
+  data['status_show'] = entity.statusShow;
+  data['created_at'] = entity.createdAt;
+  data['action_list'] = entity.actionList;
+  return data;
+}
+
+extension LabourRequestSGListRowsExtension on LabourRequestSGListRows {
+  LabourRequestSGListRows copyWith({
+    String? requestId,
+    String? outletName,
+    String? jobTitle,
+    int? needNum,
+    String? jobDate,
+    String? startTime,
+    String? endTime,
+    String? status,
+    String? statusShow,
+    String? createdAt,
+    List<String>? actionList,
+  }) {
+    return LabourRequestSGListRows()
+      ..requestId = requestId ?? this.requestId
+      ..outletName = outletName ?? this.outletName
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..needNum = needNum ?? this.needNum
+      ..jobDate = jobDate ?? this.jobDate
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..status = status ?? this.status
+      ..statusShow = statusShow ?? this.statusShow
+      ..createdAt = createdAt ?? this.createdAt
+      ..actionList = actionList ?? this.actionList;
+  }
+}

+ 289 - 73
packages/cs_domain/lib/repository/labour_sg_repository.dart

@@ -16,6 +16,9 @@ import 'package:shared/utils/util.dart';
 
 import '../constants/api_constants.dart';
 import '../entity/response/job_list_s_g_entity.dart';
+import '../entity/response/labour_request_index_entity.dart';
+import '../entity/response/labour_request_s_g_edit_index_entity.dart';
+import '../entity/response/labour_request_s_g_list_entity.dart';
 
 /// 用工相关(新加坡)
 class LabourSGRepository extends GetxService {
@@ -551,17 +554,16 @@ class LabourSGRepository extends GetxService {
     }
 
     return result.convert<LabourRequestSGCountList>();
-
-
   }
 
   /// 添加用工请求的选项数据
   Future<HttpResult<LabourRequestSGAddIndexEntity>> fetchLabourRequestAddIndex({
+    bool isShowLoadingDialog = true,
     CancelToken? cancelToken,
   }) async {
     final result = await httpProvider.requestNetResult(
       ApiConstants.apiLabourRequestAddIndexSG,
-      isShowLoadingDialog: true,
+      isShowLoadingDialog: isShowLoadingDialog,
       cancelToken: cancelToken,
     );
 
@@ -576,73 +578,6 @@ class LabourSGRepository extends GetxService {
     return result.convert();
   }
 
-  /// 删除工作标题的提交
-  Future<HttpResult> submitLabourRequestAdd(
-    String? jobTitleId,
-    String? startTime,
-    String? endTime,
-    String? repeatStart,
-    String? repeatEnd,
-    String? outletId,
-    int sexLimit,
-    String? maleLimit,
-    String? femaleLimit,
-    String? needNum,
-    String? requestType,
-    String? remark, {
-    CancelToken? cancelToken,
-  }) async {
-    //参数
-    Map<String, String> params = {};
-
-    params['job_title_id'] = jobTitleId ?? "";
-    params['start_time'] = startTime ?? "";
-    params['end_time'] = endTime ?? "";
-    params['outlet_id'] = outletId ?? "";
-
-    params['sex_limit'] = sexLimit.toString();
-
-    if (sexLimit == 1) {
-      params['male_limit'] = maleLimit ?? "0";
-      params['female_limit'] = femaleLimit ?? "0";
-      // params['need_num'] = (int.parse(maleLimit ?? "0") + int.parse(femaleLimit ?? "0")).toString();  //不传 need_num 字段
-    } else {
-      params['need_num'] = needNum ?? "0";
-    }
-
-    if (Utils.isNotEmpty(repeatStart)) {
-      params['repeat_start'] = repeatStart ?? "";
-    }
-
-    if (Utils.isNotEmpty(repeatEnd)) {
-      params['repeat_end'] = repeatEnd ?? "";
-    }
-
-    if (Utils.isNotEmpty(requestType)) {
-      params['request_type'] = requestType ?? "";
-    }
-
-    if (Utils.isNotEmpty(remark)) {
-      params['remark'] = remark ?? "";
-    }
-
-    final result = await httpProvider.requestNetResult(
-      ApiConstants.apiLabourRequestAddSubmitSG,
-      method: HttpMethod.POST,
-      params: params,
-      networkDebounce: true,
-      isShowLoadingDialog: true,
-      cancelToken: cancelToken,
-    );
-
-    //根据返回的结果,封装原始数据为Bean/Entity对象
-    if (result.isSuccess) {
-      //重新赋值data或list
-      return result.convert();
-    }
-    return result.convert();
-  }
-
   //用工请求的查询选项(Job List)
   Future<HttpResult<JobListIndexSGEntity>> fetchJobListIndex({
     CancelToken? cancelToken,
@@ -712,9 +647,9 @@ class LabourSGRepository extends GetxService {
 
   /// 根据ID获取主列表的Item数据,用于刷新Item
   Future<HttpResult<JobListSGEntity>> fetchJobListByIds(
-      String? jobId, {
-        CancelToken? cancelToken,
-      }) async {
+    String? jobId, {
+    CancelToken? cancelToken,
+  }) async {
     //参数
     Map<String, String> params = {};
     params["cur_page"] = "1";
@@ -901,4 +836,285 @@ class LabourSGRepository extends GetxService {
     }
     return result.convert();
   }
+
+  // V2 - 新版的LabourRequest 改动
+
+  /// 获取用工请求的筛选选项
+  Future<HttpResult<LabourRequestIndexEntity>> fetchLabourRequestSGIndex({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestIndex,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = LabourRequestIndexEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<LabourRequestIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 获取用工请求的主列表
+  Future<HttpResult<LabourRequestSGListEntity>> fetchLabourRequestSGList(
+    String? keyword,
+    String? startDate,
+    String? endDate,
+    String? statusId,
+    String? departmentId, {
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "20";
+
+    if (!Utils.isEmpty(keyword)) {
+      params["job_title"] = keyword!;
+    }
+    if (!Utils.isEmpty(startDate)) {
+      params["job_start"] = startDate!;
+    }
+    if (!Utils.isEmpty(endDate)) {
+      params["job_end"] = endDate!;
+    }
+    if (!Utils.isEmpty(statusId)) {
+      params["co_status"] = statusId!;
+    }
+    if (!Utils.isEmpty(departmentId)) {
+      params["co_department_id"] = departmentId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestList,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = LabourRequestSGListEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<LabourRequestSGListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 根据ID获取主列表的Item数据,用于刷新Item
+  Future<HttpResult<LabourRequestSGListEntity>> fetchItemByRequestId(
+    String? requestId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = "1";
+    params["page_size"] = "1";
+
+    if (!Utils.isEmpty(requestId)) {
+      params["request_id"] = requestId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestList,
+      params: params,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = LabourRequestSGListEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<LabourRequestSGListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 删除工作标题的提交
+  Future<HttpResult> submitLabourRequestAdd(
+    String? jobTitleId,
+    String? startTime,
+    String? endTime,
+    String? repeatStart,
+    String? repeatEnd,
+    String? outletId,
+    int sexLimit,
+    String? maleLimit,
+    String? femaleLimit,
+    String? needNum,
+    String? requestType,
+    String? remark, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+
+    params['job_title_id'] = jobTitleId ?? "";
+    params['start_time'] = startTime ?? "";
+    params['end_time'] = endTime ?? "";
+    params['outlet_id'] = outletId ?? "";
+
+    params['sex_limit'] = sexLimit.toString();
+
+    if (sexLimit == 1) {
+      params['male_limit'] = maleLimit ?? "0";
+      params['female_limit'] = femaleLimit ?? "0";
+      // params['need_num'] = (int.parse(maleLimit ?? "0") + int.parse(femaleLimit ?? "0")).toString();  //不传 need_num 字段
+    } else {
+      params['need_num'] = needNum ?? "0";
+    }
+
+    if (Utils.isNotEmpty(repeatStart)) {
+      params['repeat_start'] = repeatStart ?? "";
+    }
+
+    if (Utils.isNotEmpty(repeatEnd)) {
+      params['repeat_end'] = repeatEnd ?? "";
+    }
+
+    if (Utils.isNotEmpty(requestType)) {
+      params['request_type'] = requestType ?? "";
+    }
+
+    if (Utils.isNotEmpty(remark)) {
+      params['remark'] = remark ?? "";
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestAddSubmitSG,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 用工的编辑详情
+  Future<HttpResult<LabourRequestSGEditIndexEntity>> fetchLabourRequestEditDetail(
+    String? requestId, {
+    bool isShowLoadingDialog = true,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params['request_id'] = requestId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestEditDetail,
+      params: params,
+      isShowLoadingDialog: isShowLoadingDialog,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = LabourRequestSGEditIndexEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<LabourRequestSGEditIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 编辑工作标题的提交
+  Future<HttpResult> submitLabourRequestEdit(
+    String? requestId,
+    String? startTime,
+    String? endTime,
+    String? outletId,
+    int sexLimit,
+    String? maleLimit,
+    String? femaleLimit,
+    String? needNum,
+    String? requestType,
+    String? remark, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+
+    params['request_id'] = requestId ?? "";
+    params['start_time'] = startTime ?? "";
+    params['end_time'] = endTime ?? "";
+    params['outlet_id'] = outletId ?? "";
+
+    params['sex_limit'] = sexLimit.toString();
+
+    if (sexLimit == 1) {
+      params['male_limit'] = maleLimit ?? "0";
+      params['female_limit'] = femaleLimit ?? "0";
+      // params['need_num'] = (int.parse(maleLimit ?? "0") + int.parse(femaleLimit ?? "0")).toString();  //不传 need_num 字段
+    } else {
+      params['need_num'] = needNum ?? "0";
+    }
+
+    if (Utils.isNotEmpty(requestType)) {
+      params['request_type'] = requestType ?? "";
+    }
+
+    if (Utils.isNotEmpty(remark)) {
+      params['remark'] = remark ?? "";
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestEditSubmit,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 删除新加坡的用工请求
+  Future<HttpResult> deleteLabourRequestSG(
+    String? requestId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+
+    params['request_id'] = requestId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestDelete,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
 }

+ 1 - 1
packages/cs_plugin_platform/lib/engine/network/network_engine.dart

@@ -51,7 +51,7 @@ class NetworkEngine {
     dio.interceptors.add(CacheControlInterceptor()); //处理 Http Get 请求缓存策略
 
     if (!kReleaseMode) {
-      dio.interceptors.add(LogInterceptor(responseBody: false)); //默认的 Dio 的 Log 打印
+      dio.interceptors.add(LogInterceptor(responseBody: false)); //默认的 Dio 自带的 Log 打印
     }
 
     if (interceptors != null) {

+ 1 - 0
packages/cs_router/lib/path/router_path.dart

@@ -52,6 +52,7 @@ class RouterPath {
   static const jobTemplateAddSG = '/job/template/add/sg'; //模板添加
   static const labourRequestSG = '/labour/request/sg'; //用工首页
   static const labourRequestAddSG = '/labour/request/add/sg'; //用工请求添加
+  static const labourRequestEditSG = '/job/template/edit/sg'; //模板编辑与详情
 
   //新加坡的工作列表
   static const jobListSG = '/job/list/sg'; //工作列表(新加坡)