瀏覽代碼

job list 的列表与Applied 的列表

liukai 8 月之前
父節點
當前提交
de8aaafc16
共有 45 個文件被更改,包括 4737 次插入19 次删除
  1. 4 5
      packages/cpt_auth/lib/modules/main/main_controller.dart
  2. 418 0
      packages/cpt_job/lib/modules/job_applied/applied_staff_item.dart
  3. 280 0
      packages/cpt_job/lib/modules/job_applied/job_applied_controller.dart
  4. 209 0
      packages/cpt_job/lib/modules/job_applied/job_applied_page.dart
  5. 14 0
      packages/cpt_job/lib/modules/job_applied/job_applied_state.dart
  6. 204 0
      packages/cpt_job/lib/modules/job_list/job_list_controller.dart
  7. 362 0
      packages/cpt_job/lib/modules/job_list/job_list_filter.dart
  8. 209 0
      packages/cpt_job/lib/modules/job_list/job_list_item.dart
  9. 146 0
      packages/cpt_job/lib/modules/job_list/job_list_page.dart
  10. 18 0
      packages/cpt_job/lib/modules/job_list/job_list_state.dart
  11. 42 0
      packages/cpt_job/lib/modules/job_list_detail/job_list_detail_controller.dart
  12. 238 0
      packages/cpt_job/lib/modules/job_list_detail/job_list_detail_page.dart
  13. 30 0
      packages/cpt_job/lib/modules/job_list_detail/job_list_detail_state.dart
  14. 5 0
      packages/cpt_job/lib/router/job_service_impl.dart
  15. 20 3
      packages/cpt_job/lib/router/page_router.dart
  16. 238 0
      packages/cpt_job/lib/widget/applied_butch_modify.dart
  17. 6 6
      packages/cpt_labour/lib/modules/labour_request_list/labour_request_list_controller.dart
  18. 44 0
      packages/cs_domain/lib/constants/api_constants.dart
  19. 65 0
      packages/cs_domain/lib/entity/response/job_list_applied_edit_entity.dart
  20. 34 0
      packages/cs_domain/lib/entity/response/job_list_applied_info_entity.dart
  21. 149 0
      packages/cs_domain/lib/entity/response/job_list_applied_staff_list_entity.dart
  22. 44 0
      packages/cs_domain/lib/entity/response/job_list_applied_staff_search_entity.dart
  23. 51 0
      packages/cs_domain/lib/entity/response/job_list_detail_entity.dart
  24. 52 0
      packages/cs_domain/lib/entity/response/job_list_entity.dart
  25. 59 0
      packages/cs_domain/lib/entity/response/job_list_index_entity.dart
  26. 33 0
      packages/cs_domain/lib/entity/response/job_list_remark_view_entity.dart
  27. 84 0
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  28. 156 0
      packages/cs_domain/lib/generated/json/job_list_applied_edit_entity.g.dart
  29. 75 0
      packages/cs_domain/lib/generated/json/job_list_applied_info_entity.g.dart
  30. 351 0
      packages/cs_domain/lib/generated/json/job_list_applied_staff_list_entity.g.dart
  31. 100 0
      packages/cs_domain/lib/generated/json/job_list_applied_staff_search_entity.g.dart
  32. 107 0
      packages/cs_domain/lib/generated/json/job_list_detail_entity.g.dart
  33. 108 0
      packages/cs_domain/lib/generated/json/job_list_entity.g.dart
  34. 111 0
      packages/cs_domain/lib/generated/json/job_list_index_entity.g.dart
  35. 75 0
      packages/cs_domain/lib/generated/json/job_list_remark_view_entity.g.dart
  36. 518 0
      packages/cs_domain/lib/repository/job_repository.dart
  37. 二進制
      packages/cs_resources/assets/base_service/item_selected_icon.webp
  38. 二進制
      packages/cs_resources/assets/base_service/item_unselected_icon.webp
  39. 2 0
      packages/cs_resources/lib/generated/assets.dart
  40. 20 0
      packages/cs_resources/lib/local/language/en_US.dart
  41. 21 1
      packages/cs_resources/lib/local/language/zh_CN.dart
  42. 2 0
      packages/cs_router/lib/componentRouter/job_service.dart
  43. 10 0
      packages/cs_router/lib/path/router_path.dart
  44. 22 4
      packages/cs_widgets/lib/my_appbar.dart
  45. 1 0
      packages/cs_widgets/lib/my_text_view.dart

+ 4 - 5
packages/cpt_auth/lib/modules/main/main_controller.dart

@@ -57,12 +57,11 @@ class MainController extends GetxController {
     if (result.isSuccess) {
       final hotelInfo = result.data;
 
-      if (hotelInfo != null){
+      if (hotelInfo != null) {
         UserService.to.hotelInfo.value = hotelInfo;
 
         _handleList(hotelInfo.menus);
-
-      }else{
+      } else {
         ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
       }
     } else {
@@ -113,10 +112,10 @@ class MainController extends GetxController {
         ComponentRouterServices.labourService.startLabourRequestPage();
         break;
       case 'jobList':
-        ToastEngine.show("进入 Job List 模块");
+        ComponentRouterServices.jobService.startJobListPage();
         break;
       case 'sign':
-       ComponentRouterServices.jobService.startSignInSignOutPage();
+        ComponentRouterServices.jobService.startSignInSignOutPage();
         break;
       case 'devices':
         ToastEngine.show("进入 Devices 模块");

+ 418 - 0
packages/cpt_job/lib/modules/job_applied/applied_staff_item.dart

@@ -0,0 +1,418 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/job_list_applied_info_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_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:shared/utils/util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+/**
+ * 已申请的员工列表Item
+ */
+class AppliedStaffItem extends StatelessWidget {
+  final int index;
+  final JobListAppliedInfoEntity? jobInfo;
+  final JobListAppliedStaffListRows item;
+  final VoidCallback? onStatusAction;
+  final VoidCallback? onEditAction;
+  final VoidCallback? onRemarkAction;
+  final VoidCallback? onItemAction;
+
+  AppliedStaffItem({
+    required this.index,
+    required this.item,
+    required this.jobInfo,
+    this.onStatusAction,
+    this.onRemarkAction,
+    this.onEditAction,
+    this.onItemAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          //员工姓名
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Staff Name:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //姓名
+              MyTextView(
+                item.staffName ?? "-",
+                isFontMedium: true,
+                textColor: ColorConstants.textYellowFFBB1B,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+                textDecoration: TextDecoration.underline,
+                decorationColor: ColorConstants.textYellowFFBB1B,
+                // 可选,设置下划线的颜色
+                decorationThickness: 2.0,
+                // 可选,设置下划线的粗细
+                decorationStyle: TextDecorationStyle.solid,
+              ).expanded(),
+
+              //是否选中
+              MyAssetImage(
+                item.isSelected ? Assets.baseServiceItemSelectedIcon : Assets.baseServiceItemUnselectedIcon,
+                width: 20.5,
+                height: 20.5,
+              ),
+            ],
+          ),
+
+          // 工作开始时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Start Time:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.startTime ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 门卫签到时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Security In:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.securityIn?.time ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: item.securityIn?.changed == 1 ? ColorConstants.textRedFF6262 : Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 工作地签到时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Work In:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.workIn?.time ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: item.workIn?.changed == 1 ? ColorConstants.textRedFF6262 : Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          //工作结束时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "End Time:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.endTime ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 工作地签出时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Work Out:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.workOut?.time ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: item.workOut?.changed == 1 ? ColorConstants.textRedFF6262 : Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 门卫签出时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Security Out:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.securityOut?.time ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: item.securityOut?.changed == 1 ? ColorConstants.textRedFF6262 : Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // + - Hours
+          Visibility(
+            visible: jobInfo?.jobUnit == "hour",
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                MyTextView(
+                  "+/- Hours:".tr,
+                  isFontRegular: true,
+                  textColor: ColorConstants.textGrayAECAE5,
+                  fontSize: 14,
+                ),
+
+                //小时
+                MyTextView(
+                  Utils.isNotEmpty(item.adjustShow) ? item.adjustShow! : "0",
+                  marginLeft: 5,
+                  isFontRegular: true,
+                  textColor: Colors.white,
+                  fontSize: 14,
+                ).expanded(),
+              ],
+            ).marginOnly(top: 12),
+          ),
+
+          // Total Hours
+          Visibility(
+            visible: jobInfo?.jobUnit == "hour",
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                MyTextView(
+                  "Total Hours:".tr,
+                  isFontRegular: true,
+                  textColor: ColorConstants.textGrayAECAE5,
+                  fontSize: 14,
+                ),
+
+                //小时
+                MyTextView(
+                  item.totalShow.toString(),
+                  marginLeft: 5,
+                  isFontRegular: true,
+                  textColor: Colors.white,
+                  fontSize: 14,
+                ).expanded(),
+              ],
+            ).marginOnly(top: 12),
+          ),
+
+          // Total Rooms
+          Visibility(
+            visible: jobInfo?.jobUnit != "hour",
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                MyTextView(
+                  "Total Rooms:".tr,
+                  isFontRegular: true,
+                  textColor: ColorConstants.textGrayAECAE5,
+                  fontSize: 14,
+                ),
+
+                //小时
+                MyTextView(
+                  item.totalRooms.toString(),
+                  marginLeft: 5,
+                  isFontRegular: true,
+                  textColor: Colors.white,
+                  fontSize: 14,
+                ).expanded(),
+              ],
+            ).marginOnly(top: 12),
+          ),
+
+          // 申请时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Applied At:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //发布状态
+              MyTextView(
+                item.appliedAt ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 状态
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Status:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //发布状态
+              MyTextView(
+                item.statusShow ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          //按钮组
+          Visibility(
+            visible: item.actionList?.isNotEmpty ?? false,
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              mainAxisAlignment: MainAxisAlignment.end,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                //编辑按钮
+                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),
+                ),
+
+                //状态工作流按钮
+                Visibility(
+                  visible: item.actionList?.contains("status") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onStatusAction?.call();
+                    },
+                    text: "Status".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#0AC074"),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
+                //Remark按钮
+                Visibility(
+                  visible: item.actionList?.contains("remarks") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onRemarkAction?.call();
+                    },
+                    text: "Remarks".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#56AAFF"),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+              ],
+            ).marginOnly(top: 15),
+          ),
+        ],
+      ).onTap(() {
+        onItemAction?.call();
+      }),
+    );
+  }
+}

+ 280 - 0
packages/cpt_job/lib/modules/job_applied/job_applied_controller.dart

@@ -0,0 +1,280 @@
+import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
+import 'package:domain/repository/job_repository.dart';
+import 'package:get/get.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:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../../widget/applied_butch_modify.dart';
+import 'job_applied_state.dart';
+
+class JobAppliedController extends GetxController with DioCancelableMixin {
+  final JobRepository _jobRepository = Get.find();
+  final JobAppliedState state = JobAppliedState();
+
+  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;
+    fetchAppliedStaffList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchAppliedStaffList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchAppliedStaffList();
+  }
+
+  /// 获取服务器数据,通知消息列表
+  Future fetchAppliedStaffList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    if (state.jobInfo == null) {
+      //不是并发的,顺序执行接口
+      var jobInfoResult = await _jobRepository.fetchJobAppliedInfo(
+        state.jobId,
+        cancelToken: cancelToken,
+      );
+
+      if (jobInfoResult.isSuccess) {
+        state.jobInfo = jobInfoResult.data;
+        update();
+      } else {
+        errorMessage = jobInfoResult.errorMsg;
+        changeLoadingState(LoadState.State_Error);
+        return;
+      }
+    }
+
+    // 获取 Applied 列表
+    var listResult = await _jobRepository.fetchJobAppliedStaffs(
+      state.jobId,
+      state.keyword,
+      curPage: _curPage,
+      cancelToken: cancelToken,
+    );
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.rows);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<JobListAppliedStaffListRows>? 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);
+      }
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchAppliedStaffList();
+  }
+
+  @override
+  void onClose() {
+    super.onClose();
+  }
+
+  /// 搜索员工
+  void doSearch(String keyword) {
+    state.keyword = keyword;
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  /// 清空筛选条件
+  void resetFiltering() {
+    state.keyword = "";
+    state.searchController.text = "";
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  /// 展示添加员工的弹窗
+  void showAddStaffDialog() {
+    ToastEngine.show("展示添加员工的弹窗");
+  }
+
+  /// 去编辑员工信息页面
+  void gotoAppliedEditPage(JobListAppliedStaffListRows data) {
+    ToastEngine.show("去编辑员工信息页面");
+  }
+
+  /// 展示评论的弹窗
+  void showRemarkDialog(JobListAppliedStaffListRows data) {
+    ToastEngine.show("展示评论的弹窗");
+  }
+
+  /// 去展示员工状态的工作流
+  void gotoAppliedWorkflowPage(JobListAppliedStaffListRows data) {
+    ToastEngine.show("去展示员工状态的工作流");
+  }
+
+  /// Item选中与未选中设置
+  void doSelectedOrNot(JobListAppliedStaffListRows data) {
+    data.isSelected = !data.isSelected;
+    update();
+  }
+
+  /// 批量修改的弹窗
+  void showBatchModifyDialog() async {
+    DialogEngine.show(widget: AppliedButchModify(confirmAction: (start, end) {
+      requestBatchModify(start, end);
+    }));
+  }
+
+  /// 执行批量修改的请求
+  void requestBatchModify(DateTime start, DateTime end) async {
+    var selectedList = state.datas.where((element) => element.isSelected).toList(growable: false);
+    if (selectedList.isNotEmpty) {
+      var ids = selectedList.map((e) => e.appliedId.toString()).toList(growable: false);
+      var separatedIds = ids.join(',');
+
+      //执行请求
+      var result = await _jobRepository.batchEditStaffCheckTime(
+        state.jobId,
+        separatedIds,
+        DateTimeUtils.formatDate(start),
+        DateTimeUtils.formatDate(end),
+        cancelToken: cancelToken,
+      );
+
+      if (result.isSuccess) {
+        NotifyEngine.showSuccess("Successful".tr);
+
+        //调用接口刷新指定的Staff的信息
+        fetchItemByIdAndRefreshItem(separatedIds);
+
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+        return;
+      }
+    } else {
+      ToastEngine.show("Please select the applied record".tr);
+    }
+  }
+
+  /// 批准的操作
+  void operationApprove() async {
+    //找出已经选中的员工
+    var selectedList = state.datas.where((element) => element.isSelected).toList(growable: false);
+    if (selectedList.isNotEmpty) {
+      var ids = selectedList.map((e) => e.appliedId.toString()).toList(growable: false);
+      var separatedIds = ids.join(',');
+
+      //执行请求
+      var result = await _jobRepository.submitBatchStaffApprove(separatedIds, cancelToken: cancelToken);
+
+      if (result.isSuccess) {
+        NotifyEngine.showSuccess("Successful".tr);
+
+        //调用接口刷新指定的Staff的信息
+        fetchItemByIdAndRefreshItem(separatedIds);
+
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+        return;
+      }
+    } else {
+      ToastEngine.show("Please select the applied record".tr);
+    }
+  }
+
+  /// 根据ID获取Item对象,用于刷新
+  void fetchItemByIdAndRefreshItem(String appliedIds) async {
+    var result = await _jobRepository.fetchItemByAppliedIds(
+      state.jobId,
+      appliedIds,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      var data = result.data;
+      if (data != null && data.rows != null && data.rows!.isNotEmpty) {
+        List<JobListAppliedStaffListRows> newItem = data.rows!;
+
+        // 创建一个 Map 来加速查找
+        Map<int, JobListAppliedStaffListRows> newItemMap = {for (var item in newItem) item.appliedId: item};
+
+        // 遍历 state.datas 进行替换
+        for (int i = 0; i < state.datas.length; i++) {
+          if (newItemMap.containsKey(state.datas[i].appliedId)) {
+            state.datas[i] = newItemMap[state.datas[i].appliedId]!;
+          }
+        }
+
+        //刷新
+        update();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+}

+ 209 - 0
packages/cpt_job/lib/modules/job_applied/job_applied_page.dart

@@ -0,0 +1,209 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/search_app_bar.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_staff_item.dart';
+import 'job_applied_controller.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/my_appbar.dart';
+import 'job_applied_state.dart';
+
+/**
+ * 已申请的页面,可以签到签出、加人、修改状态、评论等操作
+ */
+class JobAppliedPage extends BaseStatefulPage<JobAppliedController> {
+  JobAppliedPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? jobId) {
+    return Get.start(RouterPath.JOB_APPLIED_STAFF_LIST, arguments: {'jobId': jobId});
+  }
+
+  @override
+  JobAppliedController createRawController() {
+    return JobAppliedController();
+  }
+
+  @override
+  State<JobAppliedPage> createState() => _JobAppliedState();
+}
+
+class _JobAppliedState extends BaseState<JobAppliedPage, JobAppliedController> {
+  late JobAppliedState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.jobId = Get.arguments['jobId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appBar(
+          context,
+          state.jobInfo?.jobTitle ?? "Title".tr,
+          subTitle: "(${state.jobInfo?.jobDate ?? "-"})",
+          subTitleColor: ColorConstants.textGrayAECAE5,
+        ),
+        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: [
+                //搜索的条件
+                Row(
+                  children: [
+                    SearchAppBar(
+                      value: state.keyword,
+                      onSearch: (keyword) {
+                        controller.doSearch(keyword);
+                      },
+                      hintText: "Staff Name".tr,
+                      controller: state.searchController,
+                    ).expanded(),
+                    MyButton(
+                      onPressed: () {
+                        FocusScope.of(context).unfocus();
+                        controller.resetFiltering();
+                      },
+                      text: "Reset".tr,
+                      textColor: ColorConstants.white,
+                      backgroundColor: hexToColor("#2BA9F9", opacity: 0.5),
+                      radius: 20,
+                      minWidth: 60,
+                      minHeight: 35,
+                    ),
+                  ],
+                ).marginOnly(top: 10, left: 15, right: 15, bottom: 5),
+
+                // 添加按钮
+                Visibility(
+                  visible: state.jobInfo?.canAppend == true,
+                  child: MyButton(
+                    type: ClickType.throttle,
+                    milliseconds: 500,
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      controller.showAddStaffDialog();
+                    },
+                    text: "Add Staff".tr,
+                    textColor: ColorConstants.white,
+                    fontSize: 16,
+                    radius: 20,
+                    backgroundColor: hexToColor("#FFBB1B"),
+                    fontWeight: FontWeight.w500,
+                  ).marginOnly(left: 15, right: 15, top: 5, bottom: 10),
+                ),
+
+                //底部的列表
+                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 AppliedStaffItem(
+                            index: index,
+                            jobInfo: state.jobInfo,
+                            item: state.datas[index],
+                            onEditAction: () {
+                              controller.gotoAppliedEditPage(state.datas[index]);
+                            },
+                            onRemarkAction: () {
+                              controller.showRemarkDialog(state.datas[index]);
+                            },
+                            onStatusAction: () {
+                              controller.gotoAppliedWorkflowPage(state.datas[index]);
+                            },
+                            onItemAction: () {
+                              controller.doSelectedOrNot(state.datas[index]);
+                            },
+                          );
+                        },
+                        childCount: state.datas.length,
+                      ))
+                    ],
+                  ),
+                ).expanded(),
+
+                Row(
+                  mainAxisSize: MainAxisSize.max,
+                  children: [
+                    //批量Approve
+                    MyTextView(
+                      "Operation Approve".tr,
+                      fontSize: 17,
+                      isFontMedium: true,
+                      boxHeight: 48,
+                      onClick: (){
+                        controller.operationApprove();
+                      },
+                      alignment: Alignment.center,
+                      textAlign: TextAlign.center,
+                      textColor: Colors.white,
+                      backgroundColor: Color(0XFF0AC074),
+                    ).expanded(),
+
+                    //批量修改时间
+                    MyTextView(
+                      "Batch Modify".tr,
+                      fontSize: 17,
+                      isFontMedium: true,
+                      boxHeight: 48,
+                      onClick: (){
+                        controller.showBatchModifyDialog();
+                      },
+                      alignment: Alignment.center,
+                      textAlign: TextAlign.center,
+                      textColor: Colors.white,
+                      backgroundColor: Color(0XFFFFBB1B),
+                    ).expanded(),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 14 - 0
packages/cpt_job/lib/modules/job_applied/job_applied_state.dart

@@ -0,0 +1,14 @@
+import 'package:domain/entity/response/job_list_applied_info_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
+import 'package:flutter/material.dart';
+
+class JobAppliedState {
+  //筛选条件
+  final TextEditingController searchController = TextEditingController();
+  String keyword = "";
+
+  String? jobId;
+  JobListAppliedInfoEntity? jobInfo; //指定工作的简短信息
+
+  List<JobListAppliedStaffListRows> datas = []; //Applied的员工列表
+}

+ 204 - 0
packages/cpt_job/lib/modules/job_list/job_list_controller.dart

@@ -0,0 +1,204 @@
+import 'package:cpt_job/modules/job_list_detail/job_list_detail_page.dart';
+import 'package:domain/entity/response/job_list_entity.dart';
+import 'package:domain/entity/response/job_list_index_entity.dart';
+import 'package:domain/repository/job_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/engine/dialog/dialog_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:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../job_applied/job_applied_page.dart';
+import 'job_list_filter.dart';
+import 'job_list_state.dart';
+
+class JobListController extends GetxController with DioCancelableMixin {
+  final JobRepository _jobRepository = Get.find();
+  final JobListState state = JobListState();
+
+  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;
+    fetchNotifyList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchNotifyList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchNotifyList();
+  }
+
+  /// 获取服务器数据,通知消息列表
+  Future fetchNotifyList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    // 并发执行两个请求
+    var futures = [
+      _jobRepository.fetchJobListTable(
+        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
+          ? _jobRepository.fetchJobListIndex(
+              cancelToken: cancelToken,
+            )
+          : Future(() => HttpResult(isSuccess: true).convert(data: state.indexOptions!)),
+    ];
+
+    //拿到结果
+    var results = await Future.wait(futures);
+    var listResult = results[0] as HttpResult<JobListEntity>;
+    var optionResult = results[1] as HttpResult<JobListIndexEntity>;
+
+    //选项数据
+    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<JobListRows>? 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: JobListFilter(
+          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,
+      );
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchNotifyList();
+  }
+
+  @override
+  void onClose() {
+    state.datas.clear();
+    super.onClose();
+  }
+
+  /// 去详情页面
+  void gotoJobDetailPage(JobListRows data) {
+    JobListDetailPage.startInstance(data.jobId.toString());
+  }
+
+  /// 去已申请的成员列表
+  void gotoJobAppliedPage(JobListRows data) {
+    JobAppliedPage.startInstance(data.jobId.toString());
+  }
+}

+ 362 - 0
packages/cpt_job/lib/modules/job_list/job_list_filter.dart

@@ -0,0 +1,362 @@
+import 'dart:ui';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/job_list_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 JobListFilter extends StatefulWidget {
+
+  void Function(DateTime? selectedStartDate, DateTime? selectedEndDate, String? selectedStatusId, String? selectedDepartmentId)? onFilterAction;
+  JobListIndexEntity optionResult;
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+  String? selectedStatusId;
+  String? selectedDepartmentId;
+
+  JobListFilter({
+    required this.optionResult,
+    required this.selectedStartDate,
+    required this.selectedEndDate,
+    required this.selectedStatusId,
+    required this.selectedDepartmentId,
+    this.onFilterAction,
+  });
+
+  @override
+  State<JobListFilter> createState() => _JobListFilterState();
+}
+
+class _JobListFilterState extends State<JobListFilter> {
+  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: EdgeInsets.only(left: 15, right: 15, top: 17.5, bottom: 20),
+          width: double.infinity,
+          decoration: BoxDecoration(
+            color: Colors.white,
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //部门
+              MyTextView(
+                "Outlet".tr,
+                fontSize: 14,
+                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(
+                      selectedDepartmentId == null
+                          ? ""
+                          : 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(),
+                    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: 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(
+                      selectedStatusId == null
+                          ? ""
+                          : 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!.indexWhere((department) => department.value.toString() == selectedDepartmentId);
+    }
+
+    if (selectedDepartmentIndex < 0) {
+      selectedDepartmentIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: widget.optionResult.departmentList!.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedDepartmentIndex,
+      onPickerChanged: (_, index) {
+        setState(() {
+          selectedDepartmentId = 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();
+        });
+      },
+    );
+  }
+}

+ 209 - 0
packages/cpt_job/lib/modules/job_list/job_list_item.dart

@@ -0,0 +1,209 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/job_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 JobListItem extends StatelessWidget {
+  final int index;
+  final JobListRows item;
+  final VoidCallback? onDetailAction;
+  final VoidCallback? onAppliedAction;
+
+  JobListItem({
+    required this.index,
+    required this.item,
+    this.onDetailAction,
+    this.onAppliedAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: 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.departmentName ?? "-",
+                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.jobTime ?? "-",
+                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.staffShow ?? "",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: ColorConstants.textYellowFFBB1B,
+                fontSize: 14,
+                onClick: onAppliedAction,
+              ).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: "Completed" == item.statusShow
+                    ? ColorConstants.textGreen05DC82
+                    : "Cancelled" == item.statusShow
+                        ? ColorConstants.textRedFF6262
+                        : "Revised" == item.statusShow || "Pending" == item.statusShow
+                            ? ColorConstants.textYellowFFBB1B
+                            : ColorConstants.textBlue06D9FF,
+                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),
+                ),
+              ],
+            ).marginOnly(top: 18, bottom: 2),
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 146 - 0
packages/cpt_job/lib/modules/job_list/job_list_page.dart

@@ -0,0 +1,146 @@
+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 'job_list_item.dart';
+import 'job_list_controller.dart';
+import 'job_list_state.dart';
+
+/**
+ * 用工请求的主页列表
+ */
+class JobListPage extends BaseStatefulPage<JobListController> {
+  JobListPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance() {
+    return Get.start(RouterPath.JOB_LIST);
+  }
+
+  @override
+  JobListController createRawController() {
+    return JobListController();
+  }
+
+  @override
+  State<JobListPage> createState() => _JobListState();
+}
+
+class _JobListState extends BaseState<JobListPage, JobListController> {
+  late JobListState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appSearchBar(
+          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),
+
+            //筛选图标
+            MyAssetImage(
+              Assets.baseServiceTitleBarFilterIcon,
+              width: 24,
+              height: 16.5,
+            ).onTap(() {
+              FocusScope.of(context).unfocus();
+              controller.showFilterDialog();
+            }).marginOnly(right: 15),
+          ],
+        ),
+        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: [
+                //底部的列表
+                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 JobListItem(
+                            index: index,
+                            item: state.datas[index],
+                            onDetailAction: (){
+                              controller.gotoJobDetailPage(state.datas[index]);
+                            },
+                            onAppliedAction: (){
+                              controller.gotoJobAppliedPage(state.datas[index]);
+                            },
+                          );
+                        },
+                        childCount: state.datas.length,
+                      ))
+                    ],
+                  ),
+                ).expanded(),
+              ],
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 18 - 0
packages/cpt_job/lib/modules/job_list/job_list_state.dart

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

+ 42 - 0
packages/cpt_job/lib/modules/job_list_detail/job_list_detail_controller.dart

@@ -0,0 +1,42 @@
+import 'package:domain/repository/job_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'job_list_detail_state.dart';
+
+class JobListDetailController extends GetxController with DioCancelableMixin {
+  final JobRepository _jobRepository = Get.find();
+  final JobListDetailState state = JobListDetailState();
+
+
+  /// 获取工作详情数据
+  void fetchJobListDetail() async {
+    var result = await _jobRepository.fetchJobListDetail(
+      state.jobId,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      state.jobListDetail = result.data;
+      state.selectedStartTime = state.jobListDetail?.startTime;
+      state.selectedEndTime = state.jobListDetail?.endTime;
+      state.noStaff = state.jobListDetail?.needNum.toString() == "0" ? "" : state.jobListDetail?.needNum.toString();
+      var needNumController = state.formData['no_of_staff']!['controller'];
+      needNumController.text = state.noStaff;
+      state.selectedJobTitle = state.jobListDetail?.jobTitle;
+      state.selectedDepartmentId = state.jobListDetail?.departmentId.toString();
+
+      update();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchJobListDetail();
+  }
+
+}

+ 238 - 0
packages/cpt_job/lib/modules/job_list_detail/job_list_detail_page.dart

@@ -0,0 +1,238 @@
+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:flutter/widgets.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/my_appbar.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/no_shadow_scroll_behavior.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/round_my_text_field.dart';
+
+import 'job_list_detail_controller.dart';
+import 'job_list_detail_state.dart';
+
+class JobListDetailPage extends BaseStatefulPage<JobListDetailController> {
+  JobListDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? jobId) {
+    return Get.start(RouterPath.JOB_LIST_DETAIL, arguments: {'jobId': jobId});
+  }
+
+  @override
+  JobListDetailController createRawController() {
+    return JobListDetailController();
+  }
+
+  @override
+  State<JobListDetailPage> createState() => _JobListDetailState();
+}
+
+class _JobListDetailState extends BaseState<JobListDetailPage, JobListDetailController> {
+  late JobListDetailState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.jobId = Get.arguments['jobId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appBar(context, "Job Detail".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: EdgeInsets.only(left: 16, right: 10),
+                        margin: EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: 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,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //开始时间
+                      FormRequireText(
+                        text: "Start Time".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择时间
+                      Container(
+                        padding: EdgeInsets.only(left: 16, right: 10),
+                        margin: EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: 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.selectedStartTime ?? "-",
+                              fontSize: 14,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //结束时间
+                      FormRequireText(
+                        text: "End Time".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择时间
+                      Container(
+                        padding: EdgeInsets.only(left: 16, right: 10),
+                        margin: EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: 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.selectedEndTime ?? "-",
+                              fontSize: 14,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //工作选择部门
+                      FormRequireText(
+                        text: "Outlet".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择部门
+                      Container(
+                        padding: EdgeInsets.only(left: 16, right: 10),
+                        margin: EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: 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.selectedDepartmentId == null
+                                  ? ""
+                                  : state.jobListDetail!.departmentList?.firstWhere((element) => element.value.toString() == state.selectedDepartmentId).txt ??
+                                      "",
+                              fontSize: 14,
+                              hint: "Choose Outlet".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //需要的人数
+                      FormRequireText(
+                        text: "No. of Staff".tr,
+                      ).marginOnly(top: 15),
+
+                      //输入框(只允许输入数字)
+                      CustomTextField(
+                        formKey: "no_of_staff",
+                        marginLeft: 0,
+                        marginRight: 0,
+                        paddingTop: 0,
+                        paddingBottom: 0,
+                        height: 45,
+                        fillBackgroundColor: Color(0xFF4DCFF6).withOpacity(0.5),
+                        enabled: false,
+                        inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
+                        textInputType: TextInputType.number,
+                        formData: state.formData,
+                        textInputAction: TextInputAction.done,
+                        onSubmit: (key, value) {
+                          FocusScope.of(context).unfocus();
+                        },
+                        marginTop: 10,
+                      ),
+                    ],
+                  ).paddingOnly(left: 15, right: 15),
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 30 - 0
packages/cpt_job/lib/modules/job_list_detail/job_list_detail_state.dart

@@ -0,0 +1,30 @@
+import 'package:domain/entity/response/job_list_detail_entity.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
+
+class JobListDetailState {
+
+  String? jobId;  //编辑和详情需要用到ID
+
+  //页面对应的详情数据
+  JobListDetailEntity? jobListDetail;
+
+  //页面对应的选择的条件
+  String? selectedJobTitle;
+  String? selectedStartTime;
+  String? selectedEndTime;
+  String? selectedDepartmentId;
+  String? noStaff;  //成员数量
+
+  //表单的校验与数据
+  Map<String, Map<String, dynamic>> formData = {
+    'no_of_staff': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter No. of Staff'.tr,
+      'obsecure': false,
+    },
+  };
+
+}

+ 5 - 0
packages/cpt_job/lib/router/job_service_impl.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_job/modules/job_list/job_list_page.dart';
 import 'package:plugin_basic/basic_export.dart';
 import 'package:router/componentRouter/job_service.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -25,4 +26,8 @@ class JobServiceImpl extends GetxService implements JobService {
     SignInSignOutPage.startInstance();
   }
 
+  @override
+  void startJobListPage() {
+    JobListPage.startInstance();
+  }
 }

+ 20 - 3
packages/cpt_job/lib/router/page_router.dart

@@ -1,19 +1,36 @@
-
+import 'package:cpt_job/modules/job_applied/job_applied_page.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_detail/job_list_detail_page.dart';
 import '../modules/sign_in_sign_out/sign_in_sign_out_page.dart';
 
 class JobPageRouter {
-
   static final routes = [
-
     //签到签出
     GetPage(
       name: RouterPath.JOB_SIGN_IN_SIGN_OUT,
       page: () => SignInSignOutPage(),
     ),
 
+    //工作列表
+    GetPage(
+      name: RouterPath.JOB_LIST,
+      page: () => JobListPage(),
+    ),
+
+    //工作列表详情
+    GetPage(
+      name: RouterPath.JOB_LIST_DETAIL,
+      page: () => JobListDetailPage(),
+    ),
+
+    //工作已申请列表
+    GetPage(
+      name: RouterPath.JOB_APPLIED_STAFF_LIST,
+      page: () => JobAppliedPage(),
+    ),
 
   ];
 }

+ 238 - 0
packages/cpt_job/lib/widget/applied_butch_modify.dart

@@ -0,0 +1,238 @@
+import 'dart:typed_data';
+import 'dart:ui';
+
+import 'package:cs_resources/generated/assets.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:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:cs_resources/constants/color_constants.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/shatter/form_require_text.dart';
+import 'package:widgets/widget_export.dart';
+
+/**
+ * 批量操作修改时间的弹窗
+ */
+class AppliedButchModify extends StatefulWidget {
+  void Function(DateTime startTime, DateTime endTime)? confirmAction;
+
+  AppliedButchModify({this.confirmAction});
+
+  @override
+  State<AppliedButchModify> createState() => _AppliedButchModifyState();
+}
+
+class _AppliedButchModifyState extends State<AppliedButchModify> {
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        //Title (如果使用 Container 为最外层容器则默认为 match_parent 的效果,除非我们限制宽度和最大高度最小高度)
+        Container(
+          padding: EdgeInsets.symmetric(horizontal: 16.5),
+          width: double.infinity,
+          decoration: BoxDecoration(
+            color: Colors.white,
+            borderRadius: const BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Center(
+                child: MyTextView(
+                  "Batch Modify".tr,
+                  fontSize: 19,
+                  isFontMedium: true,
+                  textColor: ColorConstants.black,
+                  marginTop: 22,
+                  marginBottom: 20,
+                ),
+              ),
+
+
+              FormRequireText(
+                fontSize: 14,
+                textColor: ColorConstants.black33,
+                fontWeight: FontWeight.w400,
+                text: "Job Start Time".tr,
+              ),
+
+              //选择时间
+              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),
+                      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();
+              }),
+
+              //结束日期
+              FormRequireText(
+                fontSize: 14,
+                textColor: ColorConstants.black33,
+                fontWeight: FontWeight.w400,
+                text: "Job End Time".tr,
+              ).marginOnly(top: 11),
+
+              //选择结束日期
+              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),
+                      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();
+              }),
+
+              Container(
+                margin: EdgeInsets.only(top: 25),
+                color: Color(0XFFCECECE),
+                height: 0.5,
+              ),
+              Row(
+                children: [
+                  Expanded(
+                      flex: 1,
+                      child: InkWell(
+                        onTap: () {
+                          onCancel();
+                        },
+                        child: MyTextView(
+                          "Cancel".tr,
+                          fontSize: 17.5,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: Color(0XFF0085C4),
+                          cornerRadius: 3,
+                          borderWidth: 1,
+                        ),
+                      )),
+                  Container(
+                    color: Color(0xff09141F).withOpacity(0.13),
+                    width: 0.5,
+                  ),
+                  Expanded(
+                      flex: 1,
+                      child: InkWell(
+                        onTap: () async {
+                          if (selectedStartDate == null) {
+                            ToastEngine.show("Choose Start Date".tr);
+                            return;
+                          }
+
+                          if (selectedEndDate == null) {
+                            ToastEngine.show("Choose End Date".tr);
+                            return;
+                          }
+
+                          widget.confirmAction?.call(selectedStartDate!, selectedEndDate!);
+                          onCancel();
+                        },
+                        child: MyTextView(
+                          "Submit".tr,
+                          marginLeft: 10,
+                          fontSize: 17.5,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: Color(0XFF0085C4),
+                          cornerRadius: 3,
+                        ),
+                      )),
+                ],
+              ).constrained(height: 46),
+            ],
+          ),
+        ),
+      ],
+    ).constrained(width: 285);
+  }
+
+  /// 筛选开始日期
+  void pickerStartDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedStartDate,
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedStartDate = date;
+        });
+      },
+      title: "Start Date".tr,
+    );
+  }
+
+  /// 筛选结束日期
+  void pickerEndDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedEndDate ?? selectedStartDate,
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedEndDate = date;
+        });
+      },
+      title: "End Date".tr,
+    );
+  }
+
+  //取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

+ 6 - 6
packages/cpt_labour/lib/modules/labour_request_list/labour_request_list_controller.dart

@@ -46,24 +46,24 @@ class LabourRequestListController extends GetxController with DioCancelableMixin
   // Refresh 刷新事件
   Future onRefresh() async {
     _curPage = 1;
-    fetchNotifyList();
+    fetchLabourRequestList();
   }
 
   // Refresh 加载事件
   Future loadMore() async {
     _curPage++;
-    fetchNotifyList();
+    fetchLabourRequestList();
   }
 
   // 重试请求
   Future retryRequest() async {
     _curPage = 1;
     _needShowPlaceholder = true;
-    fetchNotifyList();
+    fetchLabourRequestList();
   }
 
-  /// 获取服务器数据,通知消息列表
-  Future fetchNotifyList() async {
+  /// 获取列表数据
+  Future fetchLabourRequestList() async {
     if (_needShowPlaceholder) {
       changeLoadingState(LoadState.State_Loading);
     }
@@ -230,7 +230,7 @@ class LabourRequestListController extends GetxController with DioCancelableMixin
   @override
   void onReady() {
     super.onReady();
-    fetchNotifyList();
+    fetchLabourRequestList();
 
     registerEventBus();
   }

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

@@ -50,6 +50,50 @@ class ApiConstants {
   //撤回用工请求
   static const apiLabourRequestRecall = "/index.php/api/v1/hotel/lab-req/recall";
 
+  // =========================== 工作列表 ↓=========================================
+
+  // 工作列表首页选项
+  static const apiJobListIndex = "/index.php/api/v1/hotel/job/index";
+
+  // 工作列表首页列表
+  static const apiJobListTable = "/index.php/api/v1/hotel/job/table";
+
+  // 工作列表首页详情
+  static const apiJobListDetail = "/index.php/api/v1/hotel/job/detail";
+
+  // 工作已申请员工列表-工作的信息
+  static const apiJobListAppliedJobInfo = "/index.php/api/v1/hotel/applied/index";
+
+  // 工作已申请员工列表-员工列表
+  static const apiJobListAppliedStaffList = "/index.php/api/v1/hotel/applied/table";
+
+  // 工作已申请员工列表-添加员工查询全部员工
+  static const apiJobListAppliedStaffSearch = "/index.php/api/v1/hotel/applied/staff-view";
+
+  // 工作已申请员工列表-添加员工提交
+  static const apiJobListAppliedStaffAdd = "/index.php/api/v1/hotel/applied/staff-submit";
+
+  // 工作已申请员工列表-批量修改员工状态
+  static const apiJobListAppliedStaffBatchEdit = "/index.php/api/v1/hotel/applied/batch-edit";
+
+  // 工作已申请员工列表-编辑员工信息的详情数据
+  static const apiJobListAppliedStaffEditIndex = "/index.php/api/v1/hotel/applied/edit-view";
+
+  // 工作已申请员工列表-编辑员工信息提交
+  static const apiJobListAppliedStaffEditSubmit = "/index.php/api/v1/hotel/applied/edit-submit";
+
+  // 工作已申请员工列表-评价员工的详情数据
+  static const apiJobListAppliedStaffReviewIndex = "/index.php/api/v1/hotel/applied/remark-view";
+
+  // 工作已申请员工列表-评价员工的提交
+  static const apiJobListAppliedStaffReviewSubmit = "/index.php/api/v1/hotel/applied/remark-submit";
+
+  // 工作已申请员工列表-评价员工的提交
+  static const apiJobListAppliedStaffStateWorkflow = "/index.php/api/v1/hotel/applied/status-view";
+
+  // 工作已申请员工列表- 提交指定员工们到审核流程
+  static const apiJobListAppliedApprove = "/index.php/api/v1/hotel/applied/approve";
+
   // =========================== 签到签出 ↓=========================================
 
   // 用户签到签出列表

+ 65 - 0
packages/cs_domain/lib/entity/response/job_list_applied_edit_entity.dart

@@ -0,0 +1,65 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_applied_edit_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_applied_edit_entity.g.dart';
+
+@JsonSerializable()
+class JobListAppliedEditEntity {
+	@JSONField(name: "applied_id")
+	int appliedId = 0;
+	@JSONField(name: "member_name")
+	String? memberName = null;
+	@JSONField(name: "job_unit")
+	String? jobUnit = null;
+	@JSONField(name: "start_time")
+	String? startTime = null;
+	@JSONField(name: "end_time")
+	String? endTime = null;
+	@JSONField(name: "security_in")
+	String? securityIn = null;
+	@JSONField(name: "security_out")
+	String? securityOut = null;
+	@JSONField(name: "work_in")
+	String? workIn = null;
+	@JSONField(name: "work_out")
+	String? workOut = null;
+	@JSONField(name: "adjust_hours")
+	int adjustHours = 0;
+	@JSONField(name: "total_rooms")
+	int totalRooms = 0;
+	@JSONField(name: "reason_list")
+	List<JobListAppliedEditReasonList>? reasonList = [];
+	@JSONField(name: "reason_type")
+	int reasonType = 0;
+	@JSONField(name: "co_reason")
+	String? coReason = null;
+
+	JobListAppliedEditEntity();
+
+	factory JobListAppliedEditEntity.fromJson(Map<String, dynamic> json) => $JobListAppliedEditEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedEditEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedEditReasonList {
+	int value = 0;
+	String? txt = null;
+	String? checked = null;
+
+	JobListAppliedEditReasonList();
+
+	factory JobListAppliedEditReasonList.fromJson(Map<String, dynamic> json) => $JobListAppliedEditReasonListFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedEditReasonListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 34 - 0
packages/cs_domain/lib/entity/response/job_list_applied_info_entity.dart

@@ -0,0 +1,34 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_applied_info_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_applied_info_entity.g.dart';
+
+@JsonSerializable()
+class JobListAppliedInfoEntity {
+	@JSONField(name: "job_id")
+	int jobId = 0;
+	@JSONField(name: "job_title")
+	String? jobTitle = null;
+	String? department = null;
+	@JSONField(name: "job_unit")
+	String? jobUnit = null;
+	@JSONField(name: "job_date")
+	String? jobDate = null;
+	@JSONField(name: "can_append")
+	bool? canAppend = false;
+	@JSONField(name: "start_time")
+	String? startTime = null;
+	@JSONField(name: "end_time")
+	String? endTime = null;
+
+	JobListAppliedInfoEntity();
+
+	factory JobListAppliedInfoEntity.fromJson(Map<String, dynamic> json) => $JobListAppliedInfoEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedInfoEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 149 - 0
packages/cs_domain/lib/entity/response/job_list_applied_staff_list_entity.dart

@@ -0,0 +1,149 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_applied_staff_list_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_applied_staff_list_entity.g.dart';
+
+@JsonSerializable()
+class JobListAppliedStaffListEntity {
+	int total = 0;
+	List<JobListAppliedStaffListRows>? rows = [];
+
+	JobListAppliedStaffListEntity();
+
+	factory JobListAppliedStaffListEntity.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffListRows {
+	@JSONField(name: "applied_id")
+	int appliedId = 0;
+	@JSONField(name: "member_id")
+	int memberId = 0;
+	@JSONField(name: "staff_name")
+	String? staffName = null;
+	@JSONField(name: "start_time")
+	String? startTime = null;
+	@JSONField(name: "end_time")
+	String? endTime = null;
+	@JSONField(name: "adjust_show")
+	String? adjustShow = null;
+	@JSONField(name: "total_show")
+	int totalShow = 0;
+	@JSONField(name: "total_rooms")
+	int totalRooms = 0;
+	int status = 0;
+	@JSONField(name: "status_show")
+	String? statusShow = null;
+	@JSONField(name: "applied_at")
+	String? appliedAt = null;
+	@JSONField(name: "security_in")
+	JobListAppliedStaffListRowsSecurityIn? securityIn;
+	@JSONField(name: "security_out")
+	JobListAppliedStaffListRowsSecurityOut? securityOut;
+	@JSONField(name: "work_in")
+	JobListAppliedStaffListRowsWorkIn? workIn;
+	@JSONField(name: "work_out")
+	JobListAppliedStaffListRowsWorkOut? workOut;
+	@JSONField(name: "s_in")
+	int sIn = 0;
+	@JSONField(name: "s_out")
+	int sOut = 0;
+	@JSONField(name: "w_in")
+	int wIn = 0;
+	@JSONField(name: "w_out")
+	int wOut = 0;
+	@JSONField(name: "action_list")
+	List<String>? actionList = [];
+
+	bool isSelected = false;
+
+	JobListAppliedStaffListRows();
+
+	factory JobListAppliedStaffListRows.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffListRowsSecurityIn {
+	String? time = null;
+	dynamic image;
+	int changed = 0;
+
+	JobListAppliedStaffListRowsSecurityIn();
+
+	factory JobListAppliedStaffListRowsSecurityIn.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListRowsSecurityInFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListRowsSecurityInToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffListRowsSecurityOut {
+	String? time = null;
+	dynamic image;
+	int changed = 0;
+
+	JobListAppliedStaffListRowsSecurityOut();
+
+	factory JobListAppliedStaffListRowsSecurityOut.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListRowsSecurityOutFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListRowsSecurityOutToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffListRowsWorkIn {
+	String? time = null;
+	dynamic image;
+	int changed = 0;
+
+	JobListAppliedStaffListRowsWorkIn();
+
+	factory JobListAppliedStaffListRowsWorkIn.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListRowsWorkInFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListRowsWorkInToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffListRowsWorkOut {
+	String? time = null;
+	dynamic image;
+	int changed = 0;
+
+	JobListAppliedStaffListRowsWorkOut();
+
+	factory JobListAppliedStaffListRowsWorkOut.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffListRowsWorkOutFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffListRowsWorkOutToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 44 - 0
packages/cs_domain/lib/entity/response/job_list_applied_staff_search_entity.dart

@@ -0,0 +1,44 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_applied_staff_search_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_applied_staff_search_entity.g.dart';
+
+@JsonSerializable()
+class JobListAppliedStaffSearchEntity {
+	int total = 0;
+	List<JobListAppliedStaffSearchRows>? rows = [];
+
+	JobListAppliedStaffSearchEntity();
+
+	factory JobListAppliedStaffSearchEntity.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffSearchEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffSearchEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListAppliedStaffSearchRows {
+	int id = 0;
+	String? name = null;
+	String? sex = null;
+	String? phone = null;
+	String? nric = null;
+	String? avatar = null;
+	@JSONField(name: "apply_state")
+	int applyState = 0;
+
+	JobListAppliedStaffSearchRows();
+
+	factory JobListAppliedStaffSearchRows.fromJson(Map<String, dynamic> json) => $JobListAppliedStaffSearchRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListAppliedStaffSearchRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 51 - 0
packages/cs_domain/lib/entity/response/job_list_detail_entity.dart

@@ -0,0 +1,51 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_detail_entity.g.dart';
+
+@JsonSerializable()
+class JobListDetailEntity {
+	@JSONField(name: "job_id")
+	int jobId = 0;
+	@JSONField(name: "job_title")
+	String? jobTitle = null;
+	@JSONField(name: "need_num")
+	int needNum = 0;
+	@JSONField(name: "department_id")
+	int departmentId = 0;
+	@JSONField(name: "start_time")
+	String? startTime = null;
+	@JSONField(name: "end_time")
+	String? endTime = null;
+	@JSONField(name: "department_list")
+	List<JobListDetailDepartmentList>? departmentList = [];
+
+	JobListDetailEntity();
+
+	factory JobListDetailEntity.fromJson(Map<String, dynamic> json) => $JobListDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListDetailDepartmentList {
+	int? value = 0;
+	String? txt = null;
+	String? selected = null;
+
+	JobListDetailDepartmentList();
+
+	factory JobListDetailDepartmentList.fromJson(Map<String, dynamic> json) => $JobListDetailDepartmentListFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListDetailDepartmentListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 52 - 0
packages/cs_domain/lib/entity/response/job_list_entity.dart

@@ -0,0 +1,52 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_entity.g.dart';
+
+@JsonSerializable()
+class JobListEntity {
+	int total = 0;
+	List<JobListRows>? rows = [];
+
+	JobListEntity();
+
+	factory JobListEntity.fromJson(Map<String, dynamic> json) => $JobListEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListRows {
+	@JSONField(name: "job_id")
+	int jobId = 0;
+	@JSONField(name: "job_title")
+	String? jobTitle = null;
+	@JSONField(name: "job_time")
+	String? jobTime = null;
+	@JSONField(name: "department_name")
+	String? departmentName = null;
+	@JSONField(name: "staff_show")
+	String? staffShow = null;
+	@JSONField(name: "status_show")
+	String? statusShow = null;
+	@JSONField(name: "created_at")
+	String? createdAt = null;
+	@JSONField(name: "action_list")
+	List<String>? actionList = [];
+
+	JobListRows();
+
+	factory JobListRows.fromJson(Map<String, dynamic> json) => $JobListRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 59 - 0
packages/cs_domain/lib/entity/response/job_list_index_entity.dart

@@ -0,0 +1,59 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_index_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_index_entity.g.dart';
+
+@JsonSerializable()
+class JobListIndexEntity {
+	@JSONField(name: "department_list")
+	List<JobListIndexDepartmentList>? departmentList = [];
+	@JSONField(name: "status_list")
+	List<JobListIndexStatusList>? statusList = [];
+
+	JobListIndexEntity();
+
+	factory JobListIndexEntity.fromJson(Map<String, dynamic> json) => $JobListIndexEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListIndexEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListIndexDepartmentList {
+	int value = 0;
+	String? txt = null;
+	String? selected = null;
+
+	JobListIndexDepartmentList();
+
+	factory JobListIndexDepartmentList.fromJson(Map<String, dynamic> json) => $JobListIndexDepartmentListFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListIndexDepartmentListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class JobListIndexStatusList {
+	int value = 0;
+	String? txt = null;
+	String? selected = null;
+
+	JobListIndexStatusList();
+
+	factory JobListIndexStatusList.fromJson(Map<String, dynamic> json) => $JobListIndexStatusListFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListIndexStatusListToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 33 - 0
packages/cs_domain/lib/entity/response/job_list_remark_view_entity.dart

@@ -0,0 +1,33 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/job_list_remark_view_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/job_list_remark_view_entity.g.dart';
+
+@JsonSerializable()
+class JobListRemarkViewEntity {
+	@JSONField(name: "applied_id")
+	int appliedId = 0;
+	@JSONField(name: "member_name")
+	String? memberName = null;
+	@JSONField(name: "attitude_rate")
+	int attitudeRate = 0;
+	@JSONField(name: "grooming_rate")
+	int groomingRate = 0;
+	@JSONField(name: "performance_rate")
+	int performanceRate = 0;
+	@JSONField(name: "experience_rate")
+	int experienceRate = 0;
+	String? content = null;
+	String? disabled = null;
+
+	JobListRemarkViewEntity();
+
+	factory JobListRemarkViewEntity.fromJson(Map<String, dynamic> json) => $JobListRemarkViewEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $JobListRemarkViewEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

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

@@ -8,6 +8,14 @@ import 'package:domain/entity/response/attendance_entity.dart';
 import 'package:domain/entity/response/check_success_entity.dart';
 import 'package:domain/entity/response/hotel_info_entity.dart';
 import 'package:domain/entity/response/id_name_entity.dart';
+import 'package:domain/entity/response/job_list_applied_edit_entity.dart';
+import 'package:domain/entity/response/job_list_applied_info_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_search_entity.dart';
+import 'package:domain/entity/response/job_list_detail_entity.dart';
+import 'package:domain/entity/response/job_list_entity.dart';
+import 'package:domain/entity/response/job_list_index_entity.dart';
+import 'package:domain/entity/response/job_list_remark_view_entity.dart';
 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';
@@ -161,6 +169,63 @@ class JsonConvert {
     if (<IdNameEntity>[] is M) {
       return data.map<IdNameEntity>((Map<String, dynamic> e) => IdNameEntity.fromJson(e)).toList() as M;
     }
+    if (<JobListAppliedEditEntity>[] is M) {
+      return data.map<JobListAppliedEditEntity>((Map<String, dynamic> e) => JobListAppliedEditEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedEditReasonList>[] is M) {
+      return data.map<JobListAppliedEditReasonList>((Map<String, dynamic> e) => JobListAppliedEditReasonList.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedInfoEntity>[] is M) {
+      return data.map<JobListAppliedInfoEntity>((Map<String, dynamic> e) => JobListAppliedInfoEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListEntity>[] is M) {
+      return data.map<JobListAppliedStaffListEntity>((Map<String, dynamic> e) => JobListAppliedStaffListEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListRows>[] is M) {
+      return data.map<JobListAppliedStaffListRows>((Map<String, dynamic> e) => JobListAppliedStaffListRows.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListRowsSecurityIn>[] is M) {
+      return data.map<JobListAppliedStaffListRowsSecurityIn>((Map<String, dynamic> e) => JobListAppliedStaffListRowsSecurityIn.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListRowsSecurityOut>[] is M) {
+      return data.map<JobListAppliedStaffListRowsSecurityOut>((Map<String, dynamic> e) => JobListAppliedStaffListRowsSecurityOut.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListRowsWorkIn>[] is M) {
+      return data.map<JobListAppliedStaffListRowsWorkIn>((Map<String, dynamic> e) => JobListAppliedStaffListRowsWorkIn.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffListRowsWorkOut>[] is M) {
+      return data.map<JobListAppliedStaffListRowsWorkOut>((Map<String, dynamic> e) => JobListAppliedStaffListRowsWorkOut.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffSearchEntity>[] is M) {
+      return data.map<JobListAppliedStaffSearchEntity>((Map<String, dynamic> e) => JobListAppliedStaffSearchEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListAppliedStaffSearchRows>[] is M) {
+      return data.map<JobListAppliedStaffSearchRows>((Map<String, dynamic> e) => JobListAppliedStaffSearchRows.fromJson(e)).toList() as M;
+    }
+    if (<JobListDetailEntity>[] is M) {
+      return data.map<JobListDetailEntity>((Map<String, dynamic> e) => JobListDetailEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListDetailDepartmentList>[] is M) {
+      return data.map<JobListDetailDepartmentList>((Map<String, dynamic> e) => JobListDetailDepartmentList.fromJson(e)).toList() as M;
+    }
+    if (<JobListEntity>[] is M) {
+      return data.map<JobListEntity>((Map<String, dynamic> e) => JobListEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListRows>[] is M) {
+      return data.map<JobListRows>((Map<String, dynamic> e) => JobListRows.fromJson(e)).toList() as M;
+    }
+    if (<JobListIndexEntity>[] is M) {
+      return data.map<JobListIndexEntity>((Map<String, dynamic> e) => JobListIndexEntity.fromJson(e)).toList() as M;
+    }
+    if (<JobListIndexDepartmentList>[] is M) {
+      return data.map<JobListIndexDepartmentList>((Map<String, dynamic> e) => JobListIndexDepartmentList.fromJson(e)).toList() as M;
+    }
+    if (<JobListIndexStatusList>[] is M) {
+      return data.map<JobListIndexStatusList>((Map<String, dynamic> e) => JobListIndexStatusList.fromJson(e)).toList() as M;
+    }
+    if (<JobListRemarkViewEntity>[] is M) {
+      return data.map<JobListRemarkViewEntity>((Map<String, dynamic> e) => JobListRemarkViewEntity.fromJson(e)).toList() as M;
+    }
     if (<LabourRequestEditIndexEntity>[] is M) {
       return data.map<LabourRequestEditIndexEntity>((Map<String, dynamic> e) => LabourRequestEditIndexEntity.fromJson(e)).toList() as M;
     }
@@ -221,6 +286,25 @@ class JsonConvertClassCollection {
     (HotelInfoMenus).toString(): HotelInfoMenus.fromJson,
     (HotelInfoMenusChildren).toString(): HotelInfoMenusChildren.fromJson,
     (IdNameEntity).toString(): IdNameEntity.fromJson,
+    (JobListAppliedEditEntity).toString(): JobListAppliedEditEntity.fromJson,
+    (JobListAppliedEditReasonList).toString(): JobListAppliedEditReasonList.fromJson,
+    (JobListAppliedInfoEntity).toString(): JobListAppliedInfoEntity.fromJson,
+    (JobListAppliedStaffListEntity).toString(): JobListAppliedStaffListEntity.fromJson,
+    (JobListAppliedStaffListRows).toString(): JobListAppliedStaffListRows.fromJson,
+    (JobListAppliedStaffListRowsSecurityIn).toString(): JobListAppliedStaffListRowsSecurityIn.fromJson,
+    (JobListAppliedStaffListRowsSecurityOut).toString(): JobListAppliedStaffListRowsSecurityOut.fromJson,
+    (JobListAppliedStaffListRowsWorkIn).toString(): JobListAppliedStaffListRowsWorkIn.fromJson,
+    (JobListAppliedStaffListRowsWorkOut).toString(): JobListAppliedStaffListRowsWorkOut.fromJson,
+    (JobListAppliedStaffSearchEntity).toString(): JobListAppliedStaffSearchEntity.fromJson,
+    (JobListAppliedStaffSearchRows).toString(): JobListAppliedStaffSearchRows.fromJson,
+    (JobListDetailEntity).toString(): JobListDetailEntity.fromJson,
+    (JobListDetailDepartmentList).toString(): JobListDetailDepartmentList.fromJson,
+    (JobListEntity).toString(): JobListEntity.fromJson,
+    (JobListRows).toString(): JobListRows.fromJson,
+    (JobListIndexEntity).toString(): JobListIndexEntity.fromJson,
+    (JobListIndexDepartmentList).toString(): JobListIndexDepartmentList.fromJson,
+    (JobListIndexStatusList).toString(): JobListIndexStatusList.fromJson,
+    (JobListRemarkViewEntity).toString(): JobListRemarkViewEntity.fromJson,
     (LabourRequestEditIndexEntity).toString(): LabourRequestEditIndexEntity.fromJson,
     (LabourRequestEditIndexTemplateList).toString(): LabourRequestEditIndexTemplateList.fromJson,
     (LabourRequestEditIndexDepartmentList).toString(): LabourRequestEditIndexDepartmentList.fromJson,

+ 156 - 0
packages/cs_domain/lib/generated/json/job_list_applied_edit_entity.g.dart

@@ -0,0 +1,156 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_applied_edit_entity.dart';
+
+JobListAppliedEditEntity $JobListAppliedEditEntityFromJson(Map<String, dynamic> json) {
+  final JobListAppliedEditEntity jobListAppliedEditEntity = JobListAppliedEditEntity();
+  final int? appliedId = jsonConvert.convert<int>(json['applied_id']);
+  if (appliedId != null) {
+    jobListAppliedEditEntity.appliedId = appliedId;
+  }
+  final String? memberName = jsonConvert.convert<String>(json['member_name']);
+  if (memberName != null) {
+    jobListAppliedEditEntity.memberName = memberName;
+  }
+  final String? jobUnit = jsonConvert.convert<String>(json['job_unit']);
+  if (jobUnit != null) {
+    jobListAppliedEditEntity.jobUnit = jobUnit;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    jobListAppliedEditEntity.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    jobListAppliedEditEntity.endTime = endTime;
+  }
+  final String? securityIn = jsonConvert.convert<String>(json['security_in']);
+  if (securityIn != null) {
+    jobListAppliedEditEntity.securityIn = securityIn;
+  }
+  final String? securityOut = jsonConvert.convert<String>(json['security_out']);
+  if (securityOut != null) {
+    jobListAppliedEditEntity.securityOut = securityOut;
+  }
+  final String? workIn = jsonConvert.convert<String>(json['work_in']);
+  if (workIn != null) {
+    jobListAppliedEditEntity.workIn = workIn;
+  }
+  final String? workOut = jsonConvert.convert<String>(json['work_out']);
+  if (workOut != null) {
+    jobListAppliedEditEntity.workOut = workOut;
+  }
+  final int? adjustHours = jsonConvert.convert<int>(json['adjust_hours']);
+  if (adjustHours != null) {
+    jobListAppliedEditEntity.adjustHours = adjustHours;
+  }
+  final int? totalRooms = jsonConvert.convert<int>(json['total_rooms']);
+  if (totalRooms != null) {
+    jobListAppliedEditEntity.totalRooms = totalRooms;
+  }
+  final List<JobListAppliedEditReasonList>? reasonList = (json['reason_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListAppliedEditReasonList>(e) as JobListAppliedEditReasonList).toList();
+  if (reasonList != null) {
+    jobListAppliedEditEntity.reasonList = reasonList;
+  }
+  final int? reasonType = jsonConvert.convert<int>(json['reason_type']);
+  if (reasonType != null) {
+    jobListAppliedEditEntity.reasonType = reasonType;
+  }
+  final String? coReason = jsonConvert.convert<String>(json['co_reason']);
+  if (coReason != null) {
+    jobListAppliedEditEntity.coReason = coReason;
+  }
+  return jobListAppliedEditEntity;
+}
+
+Map<String, dynamic> $JobListAppliedEditEntityToJson(JobListAppliedEditEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['applied_id'] = entity.appliedId;
+  data['member_name'] = entity.memberName;
+  data['job_unit'] = entity.jobUnit;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['security_in'] = entity.securityIn;
+  data['security_out'] = entity.securityOut;
+  data['work_in'] = entity.workIn;
+  data['work_out'] = entity.workOut;
+  data['adjust_hours'] = entity.adjustHours;
+  data['total_rooms'] = entity.totalRooms;
+  data['reason_list'] = entity.reasonList?.map((v) => v.toJson()).toList();
+  data['reason_type'] = entity.reasonType;
+  data['co_reason'] = entity.coReason;
+  return data;
+}
+
+extension JobListAppliedEditEntityExtension on JobListAppliedEditEntity {
+  JobListAppliedEditEntity copyWith({
+    int? appliedId,
+    String? memberName,
+    String? jobUnit,
+    String? startTime,
+    String? endTime,
+    String? securityIn,
+    String? securityOut,
+    String? workIn,
+    String? workOut,
+    int? adjustHours,
+    int? totalRooms,
+    List<JobListAppliedEditReasonList>? reasonList,
+    int? reasonType,
+    String? coReason,
+  }) {
+    return JobListAppliedEditEntity()
+      ..appliedId = appliedId ?? this.appliedId
+      ..memberName = memberName ?? this.memberName
+      ..jobUnit = jobUnit ?? this.jobUnit
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..securityIn = securityIn ?? this.securityIn
+      ..securityOut = securityOut ?? this.securityOut
+      ..workIn = workIn ?? this.workIn
+      ..workOut = workOut ?? this.workOut
+      ..adjustHours = adjustHours ?? this.adjustHours
+      ..totalRooms = totalRooms ?? this.totalRooms
+      ..reasonList = reasonList ?? this.reasonList
+      ..reasonType = reasonType ?? this.reasonType
+      ..coReason = coReason ?? this.coReason;
+  }
+}
+
+JobListAppliedEditReasonList $JobListAppliedEditReasonListFromJson(Map<String, dynamic> json) {
+  final JobListAppliedEditReasonList jobListAppliedEditReasonList = JobListAppliedEditReasonList();
+  final int? value = jsonConvert.convert<int>(json['value']);
+  if (value != null) {
+    jobListAppliedEditReasonList.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    jobListAppliedEditReasonList.txt = txt;
+  }
+  final String? checked = jsonConvert.convert<String>(json['checked']);
+  if (checked != null) {
+    jobListAppliedEditReasonList.checked = checked;
+  }
+  return jobListAppliedEditReasonList;
+}
+
+Map<String, dynamic> $JobListAppliedEditReasonListToJson(JobListAppliedEditReasonList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['checked'] = entity.checked;
+  return data;
+}
+
+extension JobListAppliedEditReasonListExtension on JobListAppliedEditReasonList {
+  JobListAppliedEditReasonList copyWith({
+    int? value,
+    String? txt,
+    String? checked,
+  }) {
+    return JobListAppliedEditReasonList()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..checked = checked ?? this.checked;
+  }
+}

+ 75 - 0
packages/cs_domain/lib/generated/json/job_list_applied_info_entity.g.dart

@@ -0,0 +1,75 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_applied_info_entity.dart';
+
+JobListAppliedInfoEntity $JobListAppliedInfoEntityFromJson(Map<String, dynamic> json) {
+  final JobListAppliedInfoEntity jobListAppliedInfoEntity = JobListAppliedInfoEntity();
+  final int? jobId = jsonConvert.convert<int>(json['job_id']);
+  if (jobId != null) {
+    jobListAppliedInfoEntity.jobId = jobId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    jobListAppliedInfoEntity.jobTitle = jobTitle;
+  }
+  final String? department = jsonConvert.convert<String>(json['department']);
+  if (department != null) {
+    jobListAppliedInfoEntity.department = department;
+  }
+  final String? jobUnit = jsonConvert.convert<String>(json['job_unit']);
+  if (jobUnit != null) {
+    jobListAppliedInfoEntity.jobUnit = jobUnit;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    jobListAppliedInfoEntity.jobDate = jobDate;
+  }
+  final bool? canAppend = jsonConvert.convert<bool>(json['can_append']);
+  if (canAppend != null) {
+    jobListAppliedInfoEntity.canAppend = canAppend;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    jobListAppliedInfoEntity.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    jobListAppliedInfoEntity.endTime = endTime;
+  }
+  return jobListAppliedInfoEntity;
+}
+
+Map<String, dynamic> $JobListAppliedInfoEntityToJson(JobListAppliedInfoEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['job_id'] = entity.jobId;
+  data['job_title'] = entity.jobTitle;
+  data['department'] = entity.department;
+  data['job_unit'] = entity.jobUnit;
+  data['job_date'] = entity.jobDate;
+  data['can_append'] = entity.canAppend;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  return data;
+}
+
+extension JobListAppliedInfoEntityExtension on JobListAppliedInfoEntity {
+  JobListAppliedInfoEntity copyWith({
+    int? jobId,
+    String? jobTitle,
+    String? department,
+    String? jobUnit,
+    String? jobDate,
+    bool? canAppend,
+    String? startTime,
+    String? endTime,
+  }) {
+    return JobListAppliedInfoEntity()
+      ..jobId = jobId ?? this.jobId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..department = department ?? this.department
+      ..jobUnit = jobUnit ?? this.jobUnit
+      ..jobDate = jobDate ?? this.jobDate
+      ..canAppend = canAppend ?? this.canAppend
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime;
+  }
+}

+ 351 - 0
packages/cs_domain/lib/generated/json/job_list_applied_staff_list_entity.g.dart

@@ -0,0 +1,351 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
+
+JobListAppliedStaffListEntity $JobListAppliedStaffListEntityFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListEntity jobListAppliedStaffListEntity = JobListAppliedStaffListEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    jobListAppliedStaffListEntity.total = total;
+  }
+  final List<JobListAppliedStaffListRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListAppliedStaffListRows>(e) as JobListAppliedStaffListRows).toList();
+  if (rows != null) {
+    jobListAppliedStaffListEntity.rows = rows;
+  }
+  return jobListAppliedStaffListEntity;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListEntityToJson(JobListAppliedStaffListEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension JobListAppliedStaffListEntityExtension on JobListAppliedStaffListEntity {
+  JobListAppliedStaffListEntity copyWith({
+    int? total,
+    List<JobListAppliedStaffListRows>? rows,
+  }) {
+    return JobListAppliedStaffListEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+JobListAppliedStaffListRows $JobListAppliedStaffListRowsFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListRows jobListAppliedStaffListRows = JobListAppliedStaffListRows();
+  final int? appliedId = jsonConvert.convert<int>(json['applied_id']);
+  if (appliedId != null) {
+    jobListAppliedStaffListRows.appliedId = appliedId;
+  }
+  final int? memberId = jsonConvert.convert<int>(json['member_id']);
+  if (memberId != null) {
+    jobListAppliedStaffListRows.memberId = memberId;
+  }
+  final String? staffName = jsonConvert.convert<String>(json['staff_name']);
+  if (staffName != null) {
+    jobListAppliedStaffListRows.staffName = staffName;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    jobListAppliedStaffListRows.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    jobListAppliedStaffListRows.endTime = endTime;
+  }
+  final String? adjustShow = jsonConvert.convert<String>(json['adjust_show']);
+  if (adjustShow != null) {
+    jobListAppliedStaffListRows.adjustShow = adjustShow;
+  }
+  final int? totalShow = jsonConvert.convert<int>(json['total_show']);
+  if (totalShow != null) {
+    jobListAppliedStaffListRows.totalShow = totalShow;
+  }
+  final int? totalRooms = jsonConvert.convert<int>(json['total_rooms']);
+  if (totalRooms != null) {
+    jobListAppliedStaffListRows.totalRooms = totalRooms;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    jobListAppliedStaffListRows.status = status;
+  }
+  final String? statusShow = jsonConvert.convert<String>(json['status_show']);
+  if (statusShow != null) {
+    jobListAppliedStaffListRows.statusShow = statusShow;
+  }
+  final String? appliedAt = jsonConvert.convert<String>(json['applied_at']);
+  if (appliedAt != null) {
+    jobListAppliedStaffListRows.appliedAt = appliedAt;
+  }
+  final JobListAppliedStaffListRowsSecurityIn? securityIn = jsonConvert.convert<JobListAppliedStaffListRowsSecurityIn>(json['security_in']);
+  if (securityIn != null) {
+    jobListAppliedStaffListRows.securityIn = securityIn;
+  }
+  final JobListAppliedStaffListRowsSecurityOut? securityOut = jsonConvert.convert<JobListAppliedStaffListRowsSecurityOut>(json['security_out']);
+  if (securityOut != null) {
+    jobListAppliedStaffListRows.securityOut = securityOut;
+  }
+  final JobListAppliedStaffListRowsWorkIn? workIn = jsonConvert.convert<JobListAppliedStaffListRowsWorkIn>(json['work_in']);
+  if (workIn != null) {
+    jobListAppliedStaffListRows.workIn = workIn;
+  }
+  final JobListAppliedStaffListRowsWorkOut? workOut = jsonConvert.convert<JobListAppliedStaffListRowsWorkOut>(json['work_out']);
+  if (workOut != null) {
+    jobListAppliedStaffListRows.workOut = workOut;
+  }
+  final int? sIn = jsonConvert.convert<int>(json['s_in']);
+  if (sIn != null) {
+    jobListAppliedStaffListRows.sIn = sIn;
+  }
+  final int? sOut = jsonConvert.convert<int>(json['s_out']);
+  if (sOut != null) {
+    jobListAppliedStaffListRows.sOut = sOut;
+  }
+  final int? wIn = jsonConvert.convert<int>(json['w_in']);
+  if (wIn != null) {
+    jobListAppliedStaffListRows.wIn = wIn;
+  }
+  final int? wOut = jsonConvert.convert<int>(json['w_out']);
+  if (wOut != null) {
+    jobListAppliedStaffListRows.wOut = wOut;
+  }
+  final List<String>? actionList = (json['action_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (actionList != null) {
+    jobListAppliedStaffListRows.actionList = actionList;
+  }
+  final bool? isSelected = jsonConvert.convert<bool>(json['isSelected']);
+  if (isSelected != null) {
+    jobListAppliedStaffListRows.isSelected = isSelected;
+  }
+  return jobListAppliedStaffListRows;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListRowsToJson(JobListAppliedStaffListRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['applied_id'] = entity.appliedId;
+  data['member_id'] = entity.memberId;
+  data['staff_name'] = entity.staffName;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['adjust_show'] = entity.adjustShow;
+  data['total_show'] = entity.totalShow;
+  data['total_rooms'] = entity.totalRooms;
+  data['status'] = entity.status;
+  data['status_show'] = entity.statusShow;
+  data['applied_at'] = entity.appliedAt;
+  data['security_in'] = entity.securityIn?.toJson();
+  data['security_out'] = entity.securityOut?.toJson();
+  data['work_in'] = entity.workIn?.toJson();
+  data['work_out'] = entity.workOut?.toJson();
+  data['s_in'] = entity.sIn;
+  data['s_out'] = entity.sOut;
+  data['w_in'] = entity.wIn;
+  data['w_out'] = entity.wOut;
+  data['action_list'] = entity.actionList;
+  data['isSelected'] = entity.isSelected;
+  return data;
+}
+
+extension JobListAppliedStaffListRowsExtension on JobListAppliedStaffListRows {
+  JobListAppliedStaffListRows copyWith({
+    int? appliedId,
+    int? memberId,
+    String? staffName,
+    String? startTime,
+    String? endTime,
+    String? adjustShow,
+    int? totalShow,
+    int? totalRooms,
+    int? status,
+    String? statusShow,
+    String? appliedAt,
+    JobListAppliedStaffListRowsSecurityIn? securityIn,
+    JobListAppliedStaffListRowsSecurityOut? securityOut,
+    JobListAppliedStaffListRowsWorkIn? workIn,
+    JobListAppliedStaffListRowsWorkOut? workOut,
+    int? sIn,
+    int? sOut,
+    int? wIn,
+    int? wOut,
+    List<String>? actionList,
+    bool? isSelected,
+  }) {
+    return JobListAppliedStaffListRows()
+      ..appliedId = appliedId ?? this.appliedId
+      ..memberId = memberId ?? this.memberId
+      ..staffName = staffName ?? this.staffName
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..adjustShow = adjustShow ?? this.adjustShow
+      ..totalShow = totalShow ?? this.totalShow
+      ..totalRooms = totalRooms ?? this.totalRooms
+      ..status = status ?? this.status
+      ..statusShow = statusShow ?? this.statusShow
+      ..appliedAt = appliedAt ?? this.appliedAt
+      ..securityIn = securityIn ?? this.securityIn
+      ..securityOut = securityOut ?? this.securityOut
+      ..workIn = workIn ?? this.workIn
+      ..workOut = workOut ?? this.workOut
+      ..sIn = sIn ?? this.sIn
+      ..sOut = sOut ?? this.sOut
+      ..wIn = wIn ?? this.wIn
+      ..wOut = wOut ?? this.wOut
+      ..actionList = actionList ?? this.actionList
+      ..isSelected = isSelected ?? this.isSelected;
+  }
+}
+
+JobListAppliedStaffListRowsSecurityIn $JobListAppliedStaffListRowsSecurityInFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListRowsSecurityIn jobListAppliedStaffListRowsSecurityIn = JobListAppliedStaffListRowsSecurityIn();
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    jobListAppliedStaffListRowsSecurityIn.time = time;
+  }
+  final dynamic image = json['image'];
+  if (image != null) {
+    jobListAppliedStaffListRowsSecurityIn.image = image;
+  }
+  final int? changed = jsonConvert.convert<int>(json['changed']);
+  if (changed != null) {
+    jobListAppliedStaffListRowsSecurityIn.changed = changed;
+  }
+  return jobListAppliedStaffListRowsSecurityIn;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListRowsSecurityInToJson(JobListAppliedStaffListRowsSecurityIn entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time'] = entity.time;
+  data['image'] = entity.image;
+  data['changed'] = entity.changed;
+  return data;
+}
+
+extension JobListAppliedStaffListRowsSecurityInExtension on JobListAppliedStaffListRowsSecurityIn {
+  JobListAppliedStaffListRowsSecurityIn copyWith({
+    String? time,
+    dynamic image,
+    int? changed,
+  }) {
+    return JobListAppliedStaffListRowsSecurityIn()
+      ..time = time ?? this.time
+      ..image = image ?? this.image
+      ..changed = changed ?? this.changed;
+  }
+}
+
+JobListAppliedStaffListRowsSecurityOut $JobListAppliedStaffListRowsSecurityOutFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListRowsSecurityOut jobListAppliedStaffListRowsSecurityOut = JobListAppliedStaffListRowsSecurityOut();
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    jobListAppliedStaffListRowsSecurityOut.time = time;
+  }
+  final dynamic image = json['image'];
+  if (image != null) {
+    jobListAppliedStaffListRowsSecurityOut.image = image;
+  }
+  final int? changed = jsonConvert.convert<int>(json['changed']);
+  if (changed != null) {
+    jobListAppliedStaffListRowsSecurityOut.changed = changed;
+  }
+  return jobListAppliedStaffListRowsSecurityOut;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListRowsSecurityOutToJson(JobListAppliedStaffListRowsSecurityOut entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time'] = entity.time;
+  data['image'] = entity.image;
+  data['changed'] = entity.changed;
+  return data;
+}
+
+extension JobListAppliedStaffListRowsSecurityOutExtension on JobListAppliedStaffListRowsSecurityOut {
+  JobListAppliedStaffListRowsSecurityOut copyWith({
+    String? time,
+    dynamic image,
+    int? changed,
+  }) {
+    return JobListAppliedStaffListRowsSecurityOut()
+      ..time = time ?? this.time
+      ..image = image ?? this.image
+      ..changed = changed ?? this.changed;
+  }
+}
+
+JobListAppliedStaffListRowsWorkIn $JobListAppliedStaffListRowsWorkInFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListRowsWorkIn jobListAppliedStaffListRowsWorkIn = JobListAppliedStaffListRowsWorkIn();
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    jobListAppliedStaffListRowsWorkIn.time = time;
+  }
+  final dynamic image = json['image'];
+  if (image != null) {
+    jobListAppliedStaffListRowsWorkIn.image = image;
+  }
+  final int? changed = jsonConvert.convert<int>(json['changed']);
+  if (changed != null) {
+    jobListAppliedStaffListRowsWorkIn.changed = changed;
+  }
+  return jobListAppliedStaffListRowsWorkIn;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListRowsWorkInToJson(JobListAppliedStaffListRowsWorkIn entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time'] = entity.time;
+  data['image'] = entity.image;
+  data['changed'] = entity.changed;
+  return data;
+}
+
+extension JobListAppliedStaffListRowsWorkInExtension on JobListAppliedStaffListRowsWorkIn {
+  JobListAppliedStaffListRowsWorkIn copyWith({
+    String? time,
+    dynamic image,
+    int? changed,
+  }) {
+    return JobListAppliedStaffListRowsWorkIn()
+      ..time = time ?? this.time
+      ..image = image ?? this.image
+      ..changed = changed ?? this.changed;
+  }
+}
+
+JobListAppliedStaffListRowsWorkOut $JobListAppliedStaffListRowsWorkOutFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffListRowsWorkOut jobListAppliedStaffListRowsWorkOut = JobListAppliedStaffListRowsWorkOut();
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    jobListAppliedStaffListRowsWorkOut.time = time;
+  }
+  final dynamic image = json['image'];
+  if (image != null) {
+    jobListAppliedStaffListRowsWorkOut.image = image;
+  }
+  final int? changed = jsonConvert.convert<int>(json['changed']);
+  if (changed != null) {
+    jobListAppliedStaffListRowsWorkOut.changed = changed;
+  }
+  return jobListAppliedStaffListRowsWorkOut;
+}
+
+Map<String, dynamic> $JobListAppliedStaffListRowsWorkOutToJson(JobListAppliedStaffListRowsWorkOut entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time'] = entity.time;
+  data['image'] = entity.image;
+  data['changed'] = entity.changed;
+  return data;
+}
+
+extension JobListAppliedStaffListRowsWorkOutExtension on JobListAppliedStaffListRowsWorkOut {
+  JobListAppliedStaffListRowsWorkOut copyWith({
+    String? time,
+    dynamic image,
+    int? changed,
+  }) {
+    return JobListAppliedStaffListRowsWorkOut()
+      ..time = time ?? this.time
+      ..image = image ?? this.image
+      ..changed = changed ?? this.changed;
+  }
+}

+ 100 - 0
packages/cs_domain/lib/generated/json/job_list_applied_staff_search_entity.g.dart

@@ -0,0 +1,100 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_applied_staff_search_entity.dart';
+
+JobListAppliedStaffSearchEntity $JobListAppliedStaffSearchEntityFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffSearchEntity jobListAppliedStaffSearchEntity = JobListAppliedStaffSearchEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    jobListAppliedStaffSearchEntity.total = total;
+  }
+  final List<JobListAppliedStaffSearchRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListAppliedStaffSearchRows>(e) as JobListAppliedStaffSearchRows).toList();
+  if (rows != null) {
+    jobListAppliedStaffSearchEntity.rows = rows;
+  }
+  return jobListAppliedStaffSearchEntity;
+}
+
+Map<String, dynamic> $JobListAppliedStaffSearchEntityToJson(JobListAppliedStaffSearchEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension JobListAppliedStaffSearchEntityExtension on JobListAppliedStaffSearchEntity {
+  JobListAppliedStaffSearchEntity copyWith({
+    int? total,
+    List<JobListAppliedStaffSearchRows>? rows,
+  }) {
+    return JobListAppliedStaffSearchEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+JobListAppliedStaffSearchRows $JobListAppliedStaffSearchRowsFromJson(Map<String, dynamic> json) {
+  final JobListAppliedStaffSearchRows jobListAppliedStaffSearchRows = JobListAppliedStaffSearchRows();
+  final int? id = jsonConvert.convert<int>(json['id']);
+  if (id != null) {
+    jobListAppliedStaffSearchRows.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    jobListAppliedStaffSearchRows.name = name;
+  }
+  final String? sex = jsonConvert.convert<String>(json['sex']);
+  if (sex != null) {
+    jobListAppliedStaffSearchRows.sex = sex;
+  }
+  final String? phone = jsonConvert.convert<String>(json['phone']);
+  if (phone != null) {
+    jobListAppliedStaffSearchRows.phone = phone;
+  }
+  final String? nric = jsonConvert.convert<String>(json['nric']);
+  if (nric != null) {
+    jobListAppliedStaffSearchRows.nric = nric;
+  }
+  final String? avatar = jsonConvert.convert<String>(json['avatar']);
+  if (avatar != null) {
+    jobListAppliedStaffSearchRows.avatar = avatar;
+  }
+  final int? applyState = jsonConvert.convert<int>(json['apply_state']);
+  if (applyState != null) {
+    jobListAppliedStaffSearchRows.applyState = applyState;
+  }
+  return jobListAppliedStaffSearchRows;
+}
+
+Map<String, dynamic> $JobListAppliedStaffSearchRowsToJson(JobListAppliedStaffSearchRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['sex'] = entity.sex;
+  data['phone'] = entity.phone;
+  data['nric'] = entity.nric;
+  data['avatar'] = entity.avatar;
+  data['apply_state'] = entity.applyState;
+  return data;
+}
+
+extension JobListAppliedStaffSearchRowsExtension on JobListAppliedStaffSearchRows {
+  JobListAppliedStaffSearchRows copyWith({
+    int? id,
+    String? name,
+    String? sex,
+    String? phone,
+    String? nric,
+    String? avatar,
+    int? applyState,
+  }) {
+    return JobListAppliedStaffSearchRows()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..sex = sex ?? this.sex
+      ..phone = phone ?? this.phone
+      ..nric = nric ?? this.nric
+      ..avatar = avatar ?? this.avatar
+      ..applyState = applyState ?? this.applyState;
+  }
+}

+ 107 - 0
packages/cs_domain/lib/generated/json/job_list_detail_entity.g.dart

@@ -0,0 +1,107 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_detail_entity.dart';
+
+JobListDetailEntity $JobListDetailEntityFromJson(Map<String, dynamic> json) {
+  final JobListDetailEntity jobListDetailEntity = JobListDetailEntity();
+  final int? jobId = jsonConvert.convert<int>(json['job_id']);
+  if (jobId != null) {
+    jobListDetailEntity.jobId = jobId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    jobListDetailEntity.jobTitle = jobTitle;
+  }
+  final int? needNum = jsonConvert.convert<int>(json['need_num']);
+  if (needNum != null) {
+    jobListDetailEntity.needNum = needNum;
+  }
+  final int? departmentId = jsonConvert.convert<int>(json['department_id']);
+  if (departmentId != null) {
+    jobListDetailEntity.departmentId = departmentId;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    jobListDetailEntity.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    jobListDetailEntity.endTime = endTime;
+  }
+  final List<JobListDetailDepartmentList>? departmentList = (json['department_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListDetailDepartmentList>(e) as JobListDetailDepartmentList).toList();
+  if (departmentList != null) {
+    jobListDetailEntity.departmentList = departmentList;
+  }
+  return jobListDetailEntity;
+}
+
+Map<String, dynamic> $JobListDetailEntityToJson(JobListDetailEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['job_id'] = entity.jobId;
+  data['job_title'] = entity.jobTitle;
+  data['need_num'] = entity.needNum;
+  data['department_id'] = entity.departmentId;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['department_list'] = entity.departmentList?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension JobListDetailEntityExtension on JobListDetailEntity {
+  JobListDetailEntity copyWith({
+    int? jobId,
+    String? jobTitle,
+    int? needNum,
+    int? departmentId,
+    String? startTime,
+    String? endTime,
+    List<JobListDetailDepartmentList>? departmentList,
+  }) {
+    return JobListDetailEntity()
+      ..jobId = jobId ?? this.jobId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..needNum = needNum ?? this.needNum
+      ..departmentId = departmentId ?? this.departmentId
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..departmentList = departmentList ?? this.departmentList;
+  }
+}
+
+JobListDetailDepartmentList $JobListDetailDepartmentListFromJson(Map<String, dynamic> json) {
+  final JobListDetailDepartmentList jobListDetailDepartmentList = JobListDetailDepartmentList();
+  final int? value = jsonConvert.convert<int>(json['value']);
+  if (value != null) {
+    jobListDetailDepartmentList.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    jobListDetailDepartmentList.txt = txt;
+  }
+  final String? selected = jsonConvert.convert<String>(json['selected']);
+  if (selected != null) {
+    jobListDetailDepartmentList.selected = selected;
+  }
+  return jobListDetailDepartmentList;
+}
+
+Map<String, dynamic> $JobListDetailDepartmentListToJson(JobListDetailDepartmentList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['selected'] = entity.selected;
+  return data;
+}
+
+extension JobListDetailDepartmentListExtension on JobListDetailDepartmentList {
+  JobListDetailDepartmentList copyWith({
+    int? value,
+    String? txt,
+    String? selected,
+  }) {
+    return JobListDetailDepartmentList()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..selected = selected ?? this.selected;
+  }
+}

+ 108 - 0
packages/cs_domain/lib/generated/json/job_list_entity.g.dart

@@ -0,0 +1,108 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_entity.dart';
+
+JobListEntity $JobListEntityFromJson(Map<String, dynamic> json) {
+  final JobListEntity jobListEntity = JobListEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    jobListEntity.total = total;
+  }
+  final List<JobListRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListRows>(e) as JobListRows).toList();
+  if (rows != null) {
+    jobListEntity.rows = rows;
+  }
+  return jobListEntity;
+}
+
+Map<String, dynamic> $JobListEntityToJson(JobListEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension JobListEntityExtension on JobListEntity {
+  JobListEntity copyWith({
+    int? total,
+    List<JobListRows>? rows,
+  }) {
+    return JobListEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+JobListRows $JobListRowsFromJson(Map<String, dynamic> json) {
+  final JobListRows jobListRows = JobListRows();
+  final int? jobId = jsonConvert.convert<int>(json['job_id']);
+  if (jobId != null) {
+    jobListRows.jobId = jobId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    jobListRows.jobTitle = jobTitle;
+  }
+  final String? jobTime = jsonConvert.convert<String>(json['job_time']);
+  if (jobTime != null) {
+    jobListRows.jobTime = jobTime;
+  }
+  final String? departmentName = jsonConvert.convert<String>(json['department_name']);
+  if (departmentName != null) {
+    jobListRows.departmentName = departmentName;
+  }
+  final String? staffShow = jsonConvert.convert<String>(json['staff_show']);
+  if (staffShow != null) {
+    jobListRows.staffShow = staffShow;
+  }
+  final String? statusShow = jsonConvert.convert<String>(json['status_show']);
+  if (statusShow != null) {
+    jobListRows.statusShow = statusShow;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    jobListRows.createdAt = createdAt;
+  }
+  final List<String>? actionList = (json['action_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (actionList != null) {
+    jobListRows.actionList = actionList;
+  }
+  return jobListRows;
+}
+
+Map<String, dynamic> $JobListRowsToJson(JobListRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['job_id'] = entity.jobId;
+  data['job_title'] = entity.jobTitle;
+  data['job_time'] = entity.jobTime;
+  data['department_name'] = entity.departmentName;
+  data['staff_show'] = entity.staffShow;
+  data['status_show'] = entity.statusShow;
+  data['created_at'] = entity.createdAt;
+  data['action_list'] = entity.actionList;
+  return data;
+}
+
+extension JobListRowsExtension on JobListRows {
+  JobListRows copyWith({
+    int? jobId,
+    String? jobTitle,
+    String? jobTime,
+    String? departmentName,
+    String? staffShow,
+    String? statusShow,
+    String? createdAt,
+    List<String>? actionList,
+  }) {
+    return JobListRows()
+      ..jobId = jobId ?? this.jobId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..jobTime = jobTime ?? this.jobTime
+      ..departmentName = departmentName ?? this.departmentName
+      ..staffShow = staffShow ?? this.staffShow
+      ..statusShow = statusShow ?? this.statusShow
+      ..createdAt = createdAt ?? this.createdAt
+      ..actionList = actionList ?? this.actionList;
+  }
+}

+ 111 - 0
packages/cs_domain/lib/generated/json/job_list_index_entity.g.dart

@@ -0,0 +1,111 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_index_entity.dart';
+
+JobListIndexEntity $JobListIndexEntityFromJson(Map<String, dynamic> json) {
+  final JobListIndexEntity jobListIndexEntity = JobListIndexEntity();
+  final List<JobListIndexDepartmentList>? departmentList = (json['department_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListIndexDepartmentList>(e) as JobListIndexDepartmentList).toList();
+  if (departmentList != null) {
+    jobListIndexEntity.departmentList = departmentList;
+  }
+  final List<JobListIndexStatusList>? statusList = (json['status_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<JobListIndexStatusList>(e) as JobListIndexStatusList).toList();
+  if (statusList != null) {
+    jobListIndexEntity.statusList = statusList;
+  }
+  return jobListIndexEntity;
+}
+
+Map<String, dynamic> $JobListIndexEntityToJson(JobListIndexEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['department_list'] = entity.departmentList?.map((v) => v.toJson()).toList();
+  data['status_list'] = entity.statusList?.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension JobListIndexEntityExtension on JobListIndexEntity {
+  JobListIndexEntity copyWith({
+    List<JobListIndexDepartmentList>? departmentList,
+    List<JobListIndexStatusList>? statusList,
+  }) {
+    return JobListIndexEntity()
+      ..departmentList = departmentList ?? this.departmentList
+      ..statusList = statusList ?? this.statusList;
+  }
+}
+
+JobListIndexDepartmentList $JobListIndexDepartmentListFromJson(Map<String, dynamic> json) {
+  final JobListIndexDepartmentList jobListIndexDepartmentList = JobListIndexDepartmentList();
+  final int? value = jsonConvert.convert<int>(json['value']);
+  if (value != null) {
+    jobListIndexDepartmentList.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    jobListIndexDepartmentList.txt = txt;
+  }
+  final String? selected = jsonConvert.convert<String>(json['selected']);
+  if (selected != null) {
+    jobListIndexDepartmentList.selected = selected;
+  }
+  return jobListIndexDepartmentList;
+}
+
+Map<String, dynamic> $JobListIndexDepartmentListToJson(JobListIndexDepartmentList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['selected'] = entity.selected;
+  return data;
+}
+
+extension JobListIndexDepartmentListExtension on JobListIndexDepartmentList {
+  JobListIndexDepartmentList copyWith({
+    int? value,
+    String? txt,
+    String? selected,
+  }) {
+    return JobListIndexDepartmentList()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..selected = selected ?? this.selected;
+  }
+}
+
+JobListIndexStatusList $JobListIndexStatusListFromJson(Map<String, dynamic> json) {
+  final JobListIndexStatusList jobListIndexStatusList = JobListIndexStatusList();
+  final int? value = jsonConvert.convert<int>(json['value']);
+  if (value != null) {
+    jobListIndexStatusList.value = value;
+  }
+  final String? txt = jsonConvert.convert<String>(json['txt']);
+  if (txt != null) {
+    jobListIndexStatusList.txt = txt;
+  }
+  final String? selected = jsonConvert.convert<String>(json['selected']);
+  if (selected != null) {
+    jobListIndexStatusList.selected = selected;
+  }
+  return jobListIndexStatusList;
+}
+
+Map<String, dynamic> $JobListIndexStatusListToJson(JobListIndexStatusList entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['value'] = entity.value;
+  data['txt'] = entity.txt;
+  data['selected'] = entity.selected;
+  return data;
+}
+
+extension JobListIndexStatusListExtension on JobListIndexStatusList {
+  JobListIndexStatusList copyWith({
+    int? value,
+    String? txt,
+    String? selected,
+  }) {
+    return JobListIndexStatusList()
+      ..value = value ?? this.value
+      ..txt = txt ?? this.txt
+      ..selected = selected ?? this.selected;
+  }
+}

+ 75 - 0
packages/cs_domain/lib/generated/json/job_list_remark_view_entity.g.dart

@@ -0,0 +1,75 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/job_list_remark_view_entity.dart';
+
+JobListRemarkViewEntity $JobListRemarkViewEntityFromJson(Map<String, dynamic> json) {
+  final JobListRemarkViewEntity jobListRemarkViewEntity = JobListRemarkViewEntity();
+  final int? appliedId = jsonConvert.convert<int>(json['applied_id']);
+  if (appliedId != null) {
+    jobListRemarkViewEntity.appliedId = appliedId;
+  }
+  final String? memberName = jsonConvert.convert<String>(json['member_name']);
+  if (memberName != null) {
+    jobListRemarkViewEntity.memberName = memberName;
+  }
+  final int? attitudeRate = jsonConvert.convert<int>(json['attitude_rate']);
+  if (attitudeRate != null) {
+    jobListRemarkViewEntity.attitudeRate = attitudeRate;
+  }
+  final int? groomingRate = jsonConvert.convert<int>(json['grooming_rate']);
+  if (groomingRate != null) {
+    jobListRemarkViewEntity.groomingRate = groomingRate;
+  }
+  final int? performanceRate = jsonConvert.convert<int>(json['performance_rate']);
+  if (performanceRate != null) {
+    jobListRemarkViewEntity.performanceRate = performanceRate;
+  }
+  final int? experienceRate = jsonConvert.convert<int>(json['experience_rate']);
+  if (experienceRate != null) {
+    jobListRemarkViewEntity.experienceRate = experienceRate;
+  }
+  final String? content = jsonConvert.convert<String>(json['content']);
+  if (content != null) {
+    jobListRemarkViewEntity.content = content;
+  }
+  final String? disabled = jsonConvert.convert<String>(json['disabled']);
+  if (disabled != null) {
+    jobListRemarkViewEntity.disabled = disabled;
+  }
+  return jobListRemarkViewEntity;
+}
+
+Map<String, dynamic> $JobListRemarkViewEntityToJson(JobListRemarkViewEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['applied_id'] = entity.appliedId;
+  data['member_name'] = entity.memberName;
+  data['attitude_rate'] = entity.attitudeRate;
+  data['grooming_rate'] = entity.groomingRate;
+  data['performance_rate'] = entity.performanceRate;
+  data['experience_rate'] = entity.experienceRate;
+  data['content'] = entity.content;
+  data['disabled'] = entity.disabled;
+  return data;
+}
+
+extension JobListRemarkViewEntityExtension on JobListRemarkViewEntity {
+  JobListRemarkViewEntity copyWith({
+    int? appliedId,
+    String? memberName,
+    int? attitudeRate,
+    int? groomingRate,
+    int? performanceRate,
+    int? experienceRate,
+    String? content,
+    String? disabled,
+  }) {
+    return JobListRemarkViewEntity()
+      ..appliedId = appliedId ?? this.appliedId
+      ..memberName = memberName ?? this.memberName
+      ..attitudeRate = attitudeRate ?? this.attitudeRate
+      ..groomingRate = groomingRate ?? this.groomingRate
+      ..performanceRate = performanceRate ?? this.performanceRate
+      ..experienceRate = experienceRate ?? this.experienceRate
+      ..content = content ?? this.content
+      ..disabled = disabled ?? this.disabled;
+  }
+}

+ 518 - 0
packages/cs_domain/lib/repository/job_repository.dart

@@ -1,5 +1,13 @@
 import 'dart:typed_data';
 
+import 'package:domain/entity/response/job_list_applied_edit_entity.dart';
+import 'package:domain/entity/response/job_list_applied_info_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
+import 'package:domain/entity/response/job_list_applied_staff_search_entity.dart';
+import 'package:domain/entity/response/job_list_detail_entity.dart';
+import 'package:domain/entity/response/job_list_entity.dart';
+import 'package:domain/entity/response/job_list_index_entity.dart';
+import 'package:domain/entity/response/job_list_remark_view_entity.dart';
 import 'package:get/get.dart';
 import 'package:plugin_platform/dio_export.dart';
 import 'package:plugin_platform/http/http_provider.dart';
@@ -91,4 +99,514 @@ class JobRepository extends GetxService {
     return result.convert<CheckSuccessEntity>();
   }
 
+  /// 工作列表的筛选选项
+  Future<HttpResult<JobListIndexEntity>> fetchJobListIndex({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListIndex,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListIndexEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 获取工作列表的主列表
+  Future<HttpResult<JobListEntity>> fetchJobListTable(
+    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["start_time"] = startDate!;
+    }
+    if (!Utils.isEmpty(endDate)) {
+      params["end_time"] = endDate!;
+    }
+    if (!Utils.isEmpty(statusId)) {
+      params["status"] = statusId!;
+    }
+    if (!Utils.isEmpty(departmentId)) {
+      params["co_department_id"] = departmentId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListTable,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 工作列表的详情
+  Future<HttpResult<JobListDetailEntity>> fetchJobListDetail(
+    String? jobId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params['job_id'] = jobId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListDetail,
+      params: params,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListDetailEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListDetailEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 工作中已申请的工作信息
+  Future<HttpResult<JobListAppliedInfoEntity>> fetchJobAppliedInfo(
+    String? jobId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params['job_id'] = jobId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedJobInfo,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedInfoEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedInfoEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 工作中已申请的成员列表
+  Future<HttpResult<JobListAppliedStaffListEntity>> fetchJobAppliedStaffs(
+    String? jobId,
+    String? staffName, {
+    String? appliedId,
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "10";
+
+    if (!Utils.isEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+    if (!Utils.isEmpty(staffName)) {
+      params["staff_name"] = staffName!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffList,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedStaffListEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedStaffListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 根据ID获取主列表的Item数据,用于刷新Item
+  Future<HttpResult<JobListAppliedStaffListEntity>> fetchItemByAppliedIds(
+    String? jobId,
+    String? appliedIds, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = "1";
+    params["page_size"] = "9999";
+
+    if (!Utils.isEmpty(appliedIds)) {
+      params["applied_ids"] = appliedIds!;
+    }
+
+    if (!Utils.isEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffList,
+      params: params,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedStaffListEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedStaffListEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 添加员工的全部员工数据列表
+  Future<HttpResult<JobListAppliedStaffSearchEntity>> searchStaffList(
+    String? jobId,
+    String? keyword, {
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "20";
+
+    if (!Utils.isEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+    if (!Utils.isEmpty(keyword)) {
+      params["keyword"] = keyword!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffSearch,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedStaffSearchEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedStaffSearchEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 添加员工到工作
+  Future<HttpResult> addStaff2Job(
+    String? jobId,
+    String? staffIds, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+    if (!Utils.isEmpty(staffIds)) {
+      params["staff_ids"] = staffIds!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffAdd,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 批量修改员工的签到信息与状态
+  Future<HttpResult> batchEditStaffCheckTime(
+    String? jobId,
+    String? appliedIds,
+    String? startTime,
+    String? endTime, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(startTime)) {
+      params["start_time"] = startTime!;
+    }
+    if (!Utils.isEmpty(endTime)) {
+      params["end_time"] = endTime!;
+    }
+    if (!Utils.isEmpty(appliedIds)) {
+      params["applied_ids"] = appliedIds!;
+    }
+    if (!Utils.isEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffBatchEdit,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 获取单个员工的信息,准备修改
+  Future<HttpResult<JobListAppliedEditEntity>> fetchAppliedStaffInfo(
+    String? appliedId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffEditIndex,
+      isShowLoadingDialog: true,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedEditEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedEditEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 单独修改单个员工的信息
+  Future<HttpResult> editAppliedSingleStaffInfo(
+    String? appliedId,
+    String? startTime,
+    String? endTime,
+    String? security_in,
+    String? security_out,
+    String? work_in,
+    String? work_out,
+    String? total_rooms,
+    String? adjust_hours,
+    String? co_reason_type,
+    String? co_reason, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+    if (!Utils.isEmpty(startTime)) {
+      params["start_time"] = startTime!;
+    }
+    if (!Utils.isEmpty(endTime)) {
+      params["end_time"] = endTime!;
+    }
+    if (!Utils.isEmpty(security_in)) {
+      params["security_in"] = security_in!;
+    }
+    if (!Utils.isEmpty(security_out)) {
+      params["security_out"] = security_out!;
+    }
+    if (!Utils.isEmpty(work_in)) {
+      params["work_in"] = work_in!;
+    }
+    if (!Utils.isEmpty(work_out)) {
+      params["work_out"] = work_out!;
+    }
+    if (!Utils.isEmpty(total_rooms)) {
+      params["total_rooms"] = total_rooms!;
+    }
+    if (!Utils.isEmpty(adjust_hours)) {
+      params["adjust_hours"] = adjust_hours!;
+    }
+    if (!Utils.isEmpty(co_reason_type)) {
+      params["co_reason_type"] = co_reason_type!;
+    }
+    if (!Utils.isEmpty(co_reason)) {
+      params["co_reason"] = co_reason!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffEditSubmit,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 给员工评分的详情与选项
+  Future<HttpResult<JobListRemarkViewEntity>> fetchAppliedStaffReviewView(
+    String? appliedId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffReviewIndex,
+      isShowLoadingDialog: true,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListRemarkViewEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListRemarkViewEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 单独给单个员工评分的提交
+  Future<HttpResult> remarkAppliedSingleStaffSubmit(
+    String? appliedId,
+    String? attitude_rate,
+    String? grooming_rate,
+    String? performance_rate,
+    String? experience_rate,
+    String? content, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+    if (!Utils.isEmpty(attitude_rate)) {
+      params["attitude_rate"] = attitude_rate!;
+    }
+    if (!Utils.isEmpty(grooming_rate)) {
+      params["grooming_rate"] = grooming_rate!;
+    }
+    if (!Utils.isEmpty(performance_rate)) {
+      params["performance_rate"] = performance_rate!;
+    }
+    if (!Utils.isEmpty(experience_rate)) {
+      params["experience_rate"] = experience_rate!;
+    }
+    if (!Utils.isEmpty(content)) {
+      params["content"] = content!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedStaffReviewSubmit,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 批量提交多个员工的考勤
+  Future<HttpResult> submitBatchStaffApprove(
+    String? appliedIds, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedIds)) {
+      params["applied_ids"] = appliedIds!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobListAppliedApprove,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+// 员工状态的工作流
+
+// 员工的信息
+
+// 员工的历史申请记录
+
+// 员工的历史评价记录
 }

二進制
packages/cs_resources/assets/base_service/item_selected_icon.webp


二進制
packages/cs_resources/assets/base_service/item_unselected_icon.webp


+ 2 - 0
packages/cs_resources/lib/generated/assets.dart

@@ -9,6 +9,8 @@ class Assets {
   static const String baseLibImageDefaultPlaceholder = 'assets/base_lib/image_default_placeholder.png';
   static const String baseLibWhiteBack = 'assets/base_lib/white_back.webp';
   static const String baseServiceDialogDeleteIcon = 'assets/base_service/dialog_delete_icon.webp';
+  static const String baseServiceItemSelectedIcon = 'assets/base_service/item_selected_icon.webp';
+  static const String baseServiceItemUnselectedIcon = 'assets/base_service/item_unselected_icon.webp';
   static const String baseServicePageLoadError = 'assets/base_service/page_load_error.webp';
   static const String baseServicePageNoData = 'assets/base_service/page_no_data.webp';
   static const String baseServiceTitleBarFilterIcon = 'assets/base_service/title_bar_filter_icon.webp';

+ 20 - 0
packages/cs_resources/lib/local/language/en_US.dart

@@ -98,6 +98,26 @@ const Map<String, String> en_US = {
   'Approved': 'Approved',
   'Pending': 'Pending',
   'Rejected': 'Rejected',
+  'Completed': 'Completed',
+  'Active': 'Active',
+  'Cancelled': 'Cancelled',
+  'Revised': 'Revised',
+  'Job Detail': 'Job Detail',
+  'Add Staff': 'Add Staff',
+  'Remarks': 'Remarks',
+  'Applied At:': 'Applied At:',
+  'Total Rooms:': 'Total Rooms:',
+  'Total Hours:': 'Total Hours:',
+  '+/- Hours:': '+/- Hours:',
+  'Security Out:': 'Security Out:',
+  'Work Out:': 'Work Out:',
+  'Work In:': 'Work In:',
+  'Security In:': 'Security In:',
+  'Staff Name:': 'Staff Name:',
+  'Staff Name': 'Staff Name',
+  'Operation Approve': 'Operation Approve',
+  'Batch Modify': 'Batch Modify',
+  'Please select the applied record': 'Please select the applied record',
 
   //插件的国际化
   'Pull to refresh': 'Pull to refresh',

+ 21 - 1
packages/cs_resources/lib/local/language/zh_CN.dart

@@ -89,7 +89,7 @@ const Map<String, String> zh_CN = {
   'Message': '通知',
   'Are you sure you want to recall?': '你确定要撤回此用工请求吗?',
   'Workflow': '工作流程',
-  'Remark:': '备注:',
+  'Remark:': '评价:',
   'Audit Time:': '审核时间:',
   'Operator:': '操作人员:',
   'Designation:': '职位:',
@@ -98,6 +98,26 @@ const Map<String, String> zh_CN = {
   'Approved': '已批准',
   'Pending': '待处理',
   'Rejected': '已拒绝',
+  'Completed': '已完成',
+  'Active': '可用',
+  'Cancelled': '已取消',
+  'Revised': '已修改',
+  'Job Detail': '工作详情',
+  'Add Staff': '添加员工',
+  'Remarks': '评论',
+  'Applied At:': '申请时间:',
+  'Total Rooms:': '总房间数:',
+  'Total Hours:': '总小时:',
+  '+/- Hours:': '加/减小时:',
+  'Security Out:': '门卫签出:',
+  'Work Out:': '工作地签出:',
+  'Work In:': '工作地签到:',
+  'Security In:': '门卫签到:',
+  'Staff Name:': '员工姓名:',
+  'Staff Name': '员工姓名',
+  'Operation Approve': '操作批准',
+  'Batch Modify': '批量修改',
+  'Please select the applied record': '请选择申请记录',
 
   //插件的国际化
   'Pull to refresh': '下拉刷新',

+ 2 - 0
packages/cs_router/lib/componentRouter/job_service.dart

@@ -6,4 +6,6 @@ abstract class JobService {
 
   void startSignInSignOutPage();
 
+  void startJobListPage();
+
 }

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

@@ -16,6 +16,16 @@ class RouterPath {
   //工作-签到签出
   static const JOB_SIGN_IN_SIGN_OUT = '/job/sign_in_sign_out';
 
+  //工作-列表
+  static const JOB_LIST = '/job/list';
+  static const JOB_LIST_DETAIL = '/job/list/detail';  //查看工作的详情
+  static const JOB_APPLIED_STAFF_LIST = '/job/applied';  //指定工作中已申请的成员列表
+  static const JOB_APPLIED_STAFF_EDIT = '/job/applied/edit';  //指定工作中已申请的指定员工的信息修改(签到签出等修改)
+  static const JOB_APPLIED_STAFF_WORKFLOW = '/job/applied/workflow';  //指定工作中已申请的指定员工的信息与状态修改工作流
+  static const JOB_APPLIED_STAFF_DETAIL = '/job/applied/staff/detail';  //工作中员工的详细信息
+  static const JOB_APPLIED_STAFF_REVIEWS = '/job/applied/staff/reviews';  //工作中员工的被评价列表
+
+
   //用工请求
   static const JOB_LABOUR_REQUEST_LIST = '/labour/list'; //用工请求列表
   static const JOB_LABOUR_REQUEST_ADD = '/labour/add'; //用工请求添加

+ 22 - 4
packages/cs_widgets/lib/my_appbar.dart

@@ -14,6 +14,8 @@ class MyAppBar {
       String? backIconPath,
       double? backIconWidth,
       double? backIconHeight,
+      String? subTitle,
+      Color? subTitleColor,
       Color textColor = Colors.white,
       Color backgroundColor = Colors.transparent,
       SystemUiOverlayStyle? systemUiOverlayStyle,
@@ -35,10 +37,26 @@ class MyAppBar {
         },
       ),
       centerTitle: true,
-      title: Text(
-        title,
-        style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
-      ),
+      title: subTitle == null
+          ? Text(
+              title,
+              style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
+            )
+          : Column(
+              mainAxisSize: MainAxisSize.max,
+              mainAxisAlignment: MainAxisAlignment.center,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                Text(
+                  title,
+                  style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
+                ),
+                Text(
+                  subTitle,
+                  style: TextStyle(color: subTitleColor ?? Colors.white, fontSize: 15, fontWeight: FontWeight.w400),
+                )
+              ],
+            ),
       actions: actions,
       elevation: 0.0,
       bottom: PreferredSize(

+ 1 - 0
packages/cs_widgets/lib/my_text_view.dart

@@ -102,6 +102,7 @@ class MyTextView extends StatelessWidget {
     this.textAlign,
     this.boxWidth,
     this.boxHeight,
+    this.alignment,
     this.onClick,
     this.fontStyle,
     this.type = ClickType.none, //默认没有点击类型