Переглянути джерело

泰国的ER相关,Job的Applied相关接口

liukai 1 тиждень тому
батько
коміт
01250579d5
52 змінених файлів з 7772 додано та 6 видалено
  1. 1 1
      packages/cpt_th/lib/modules/job/applied_workflow/applied_workflow_controller.dart
  2. 436 0
      packages/cpt_th/lib/modules/job_er/applied_er/applied_er_controller.dart
  3. 474 0
      packages/cpt_th/lib/modules/job_er/applied_er/applied_er_item.dart
  4. 255 0
      packages/cpt_th/lib/modules/job_er/applied_er/applied_er_page.dart
  5. 18 0
      packages/cpt_th/lib/modules/job_er/applied_er/applied_er_state.dart
  6. 344 0
      packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_add_staff.dart
  7. 130 0
      packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_add_staff_controller.dart
  8. 241 0
      packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_butch_modify.dart
  9. 313 0
      packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_staff_reviews.dart
  10. 195 0
      packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_controller.dart
  11. 564 0
      packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_page.dart
  12. 44 0
      packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_state.dart
  13. 162 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_controller.dart
  14. 138 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_page.dart
  15. 15 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_state.dart
  16. 292 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/staff_detail_widget.dart
  17. 215 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/staff_labour_history_item.dart
  18. 108 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_controller.dart
  19. 162 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_page.dart
  20. 10 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_state.dart
  21. 151 0
      packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_staff_reviews_item.dart
  22. 98 0
      packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_controller.dart
  23. 102 0
      packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_page.dart
  24. 10 0
      packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_state.dart
  25. 228 0
      packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_workflow_item.dart
  26. 2 1
      packages/cpt_th/lib/modules/job_er/job_list_er/job_list_er_controller.dart
  27. 1 1
      packages/cpt_th/lib/modules/job_er/job_list_er/job_list_er_state.dart
  28. 35 0
      packages/cpt_th/lib/router/th_router.dart
  29. 43 0
      packages/cs_domain/lib/constants/api_constants.dart
  30. 1 1
      packages/cs_domain/lib/entity/response/job_list_applied_work_flow_entity.dart
  31. 3 0
      packages/cs_domain/lib/entity/response/job_list_remark_view_entity.dart
  32. 2 0
      packages/cs_domain/lib/entity/response/staff_labour_history_entity.dart
  33. 190 0
      packages/cs_domain/lib/entity/response/t_h_applied_edit_entity.dart
  34. 48 0
      packages/cs_domain/lib/entity/response/t_h_applied_employee_entity.dart
  35. 117 0
      packages/cs_domain/lib/entity/response/t_h_applied_index_entity.dart
  36. 114 0
      packages/cs_domain/lib/entity/response/t_h_applied_table_entity.dart
  37. 101 0
      packages/cs_domain/lib/entity/response/t_h_employee_detail_entity.dart
  38. 55 0
      packages/cs_domain/lib/entity/response/t_h_employee_remarks_entity.dart
  39. 62 0
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  40. 2 2
      packages/cs_domain/lib/generated/json/job_list_applied_work_flow_entity.g.dart
  41. 14 0
      packages/cs_domain/lib/generated/json/job_list_remark_view_entity.g.dart
  42. 7 0
      packages/cs_domain/lib/generated/json/staff_labour_history_entity.g.dart
  43. 601 0
      packages/cs_domain/lib/generated/json/t_h_applied_edit_entity.g.dart
  44. 114 0
      packages/cs_domain/lib/generated/json/t_h_applied_employee_entity.g.dart
  45. 340 0
      packages/cs_domain/lib/generated/json/t_h_applied_index_entity.g.dart
  46. 306 0
      packages/cs_domain/lib/generated/json/t_h_applied_table_entity.g.dart
  47. 284 0
      packages/cs_domain/lib/generated/json/t_h_employee_detail_entity.g.dart
  48. 121 0
      packages/cs_domain/lib/generated/json/t_h_employee_remarks_entity.g.dart
  49. 490 0
      packages/cs_domain/lib/repository/th_er_repository.dart
  50. 4 0
      packages/cs_resources/lib/local/language/en_US.dart
  51. 4 0
      packages/cs_resources/lib/local/language/zh_CN.dart
  52. 5 0
      packages/cs_router/lib/path/router_path.dart

+ 1 - 1
packages/cpt_th/lib/modules/job/applied_workflow/applied_workflow_controller.dart

@@ -7,7 +7,7 @@ import 'package:widgets/widget_export.dart';
 
 import 'applied_workflow_state.dart';
 
-/**
+/*
  * 已申请的员工状态审核流
  */
 class  AppliedWorkflowController extends GetxController with DioCancelableMixin{

+ 436 - 0
packages/cpt_th/lib/modules/job_er/applied_er/applied_er_controller.dart

@@ -0,0 +1,436 @@
+import 'package:cpt_th/modules/job_er/applied_er_edit/applied_er_edit_page.dart';
+import 'package:domain/entity/response/t_h_applied_index_entity.dart';
+import 'package:domain/entity/response/t_h_applied_table_entity.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_basic/constants/app_constant.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/dialog/app_default_dialog.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+import 'package:widgets/widget_export.dart';
+import '../applied_er_staff_detail/applied_er_staff_detail_page.dart';
+import '../applied_er_workflow/applied_er_workflow_page.dart';
+import 'applied_er_state.dart';
+import 'widget/er_applied_add_staff.dart';
+import 'widget/er_applied_butch_modify.dart';
+import 'widget/er_applied_staff_reviews.dart';
+
+class AppliedErController extends GetxController with DioCancelableMixin {
+  final THERRepository _erRepository = Get.find();
+  final AppliedErState state = AppliedErState();
+
+  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);
+    }
+
+    // 并发执行两个请求
+    var futures = [
+      _erRepository.fetchERAppliedTable(
+        jobId: state.jobId,
+        curPage: _curPage,
+        status: state.selectedStatusId,
+        keyword: state.keyword,
+        cancelToken: cancelToken,
+      ),
+      state.jobInfo == null
+          ? _erRepository.fetchERAppliedOption(
+              jobId: state.jobId,
+              cancelToken: cancelToken,
+            )
+          : Future(() => HttpResult(isSuccess: true).convert(data: state.jobInfo!)),
+    ];
+
+    //拿到结果
+    var results = await Future.wait(futures);
+    var listResult = results[0] as HttpResult<THAppliedTableEntity>;
+    var optionResult = results[1] as HttpResult<THAppliedIndexEntity>;
+
+    //选项数据
+    if (state.jobInfo == null && optionResult.isSuccess) {
+      state.jobInfo = optionResult.data!;
+    }
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.rows);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<THAppliedTableRows>? 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();
+    registerEventBus();
+  }
+
+  @override
+  void onClose() {
+    unregisterEventBus();
+    state.datas.clear();
+    super.onClose();
+  }
+
+  // EventBus 的事件接收
+  Subscription? subscribe;
+
+  void registerEventBus() {
+    subscribe = bus.on(AppConstant.eventAppliedListRefresh, (arg) {
+      var appliedId = arg as String;
+      if (Utils.isNotEmpty(appliedId)) {
+        fetchItemByIdAndRefreshItem(appliedId);
+      } else {
+        refreshController.callRefresh();
+      }
+    });
+  }
+
+  void unregisterEventBus() {
+    bus.off(AppConstant.eventAppliedListRefresh, subscribe);
+  }
+
+  /// 搜索员工
+  void doSearch(String keyword) {
+    state.keyword = keyword;
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  /// 清空筛选条件
+  void resetFiltering() {
+    state.keyword = "";
+    state.searchController.text = "";
+    state.selectedStatusId = null;
+    state.selectedStatusName = null;
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  /// 展示添加员工的弹窗
+  void showAddStaffDialog() {
+    DialogEngine.show(
+      widget: ErAppliedAddStaff(
+        jobId: state.jobId!,
+        confirmAction: (selectedIds) {
+          //调用接口添加员工
+          _requestAddStaff2Applied(selectedIds);
+        },
+      ),
+    );
+  }
+
+  //调用接口添加员工
+  void _requestAddStaff2Applied(String selectedIds) async {
+    var result = await _erRepository.addStaff2Job(state.jobId, selectedIds, cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      var addStaffEntity = result.data;
+      List<String> filteredMessages = [];
+      if (addStaffEntity != null && addStaffEntity.resultList?.isNotEmpty == true) {
+        filteredMessages = addStaffEntity.resultList!
+            .where((resultList) => resultList.result == false && Utils.isNotEmpty(resultList.msg))
+            .map((resultList) => '${resultList.name} : ${resultList.msg!}')
+            .toList();
+      }
+
+      if (filteredMessages.isNotEmpty) {
+        //有错误信息
+        NotifyEngine.showFailure(filteredMessages.join(" , "));
+      } else {
+        //无错误信息
+        NotifyEngine.showSuccess("Successful".tr);
+        //添加成功之后刷新页面
+        refreshController.callRefresh();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+      return;
+    }
+  }
+
+  /// 去编辑员工信息页面
+  void gotoAppliedEditPage(THAppliedTableRows data) {
+    AppliedErEditPage.startInstance(data.id.toString());
+  }
+
+  /// 展示评论的弹窗
+  void showRemarkDialog(THAppliedTableRows data) async {
+    // 请求接口获取到已评论的数据
+    var result = await _erRepository.fetchAppliedStaffReviewView(data.id.toString());
+
+    if (result.isSuccess) {
+      //接口数据获取成功,展示弹窗
+      DialogEngine.show(
+        widget: ErAppliedStaffReviews(
+          appliedReviews: result.data!,
+          confirmAction: (attitudeRate, performanceRate, experienceRate, groomingRate, content) async {
+            //请求接口,提交评论
+            var submitResult = await _erRepository.remarkAppliedSingleStaffSubmit(
+              data.id,
+              attitudeRate,
+              groomingRate,
+              performanceRate,
+              experienceRate,
+              content,
+            );
+
+            if (submitResult.isSuccess) {
+              NotifyEngine.showSuccess("Successful".tr);
+            } else {
+              ToastEngine.show(submitResult.errorMsg ?? "Network Load Error".tr);
+            }
+          },
+        ),
+      );
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+      return;
+    }
+  }
+
+  /// 去展示员工状态的审核流程页面
+  void gotoAppliedWorkflowPage(THAppliedTableRows data) {
+    AppliedErWorkflowPage.startInstance(data.id.toString());
+  }
+
+  /// 去查看员工详情页面
+  void gotoStaffDetailPage(THAppliedTableRows data) {
+    AppliedErStaffDetailPage.startInstance(data.memberId);
+  }
+
+  /// Item选中与未选中设置
+  void doSelectedOrNot(THAppliedTableRows data) {
+    //只有 Approve = 3 的状态才能选中
+    // if (data.status == 3) {
+    data.isSelected = !data.isSelected;
+    update();
+    // }
+  }
+
+  /// 批量修改的弹窗
+  void showBatchModifyDialog() async {
+    // if (state.jobInfo == null) return;
+    //找出已经选中的员工(只有状态为3 Approve的状态才能修改)
+    var selectedList = state.datas.where((element) => element.isSelected /*&& element.status == 3*/).toList(growable: false);
+    if (selectedList.isNotEmpty) {
+      var ids = selectedList.map((e) => e.id.toString()).toList(growable: false);
+      var separatedIds = ids.join(',');
+
+      DialogEngine.show(
+          widget: ErAppliedButchModify(
+              selectedStartDate: DateTimeUtils.getDateTimeByMs((state.jobInfo?.job?.startTime ?? 0) * 1000),
+              selectedEndDate: DateTimeUtils.getDateTimeByMs((state.jobInfo?.job?.endTime ?? 0) * 1000),
+              confirmAction: (start, end) {
+                _requestBatchModify(start, end, separatedIds);
+              }));
+    } else {
+      ToastEngine.show("Please select the applied record".tr);
+    }
+  }
+
+  /// 执行批量修改的请求
+  void _requestBatchModify(DateTime start, DateTime end, String separatedIds) async {
+    //执行请求
+    var result = await _erRepository.batchEditStaffCheckTime(
+      separatedIds,
+      DateTimeUtils.formatDate(start, format: 'HH:mm:ss'),
+      DateTimeUtils.formatDate(end, format: 'HH:mm:ss'),
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      //调用接口刷新指定的Staff的信息
+      fetchItemByIdAndRefreshItem(separatedIds);
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+      return;
+    }
+  }
+
+  /// 批准的操作
+  void operationApprove() async {
+    // 找出已经选中的员工(只有状态为3 Approve的状态才能修改)
+    var selectedList = state.datas.where((element) => element.isSelected /*&& element.status == 3*/).toList(growable: false);
+    if (selectedList.isNotEmpty) {
+      var ids = selectedList.map((e) => e.id.toString()).toList(growable: false);
+      var separatedIds = ids.join(',');
+
+      // Are you sure 的弹窗
+      DialogEngine.show(
+        widget: AppDefaultDialog(
+          title: "Message".tr,
+          message: "Are you sure you want to setting approved?".tr,
+          confirmAction: () async {
+            //执行请求
+            var result = await _erRepository.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 _erRepository.fetchItemByAppliedIds(
+      state.jobId,
+      appliedIds,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      var data = result.data;
+      if (data != null && data.rows.isNotEmpty) {
+        List<THAppliedTableRows> newItem = data.rows;
+
+        // 创建一个 Map 来加速查找
+        Map<String, THAppliedTableRows> newItemMap = {for (var item in newItem) item.id ?? "": item};
+
+        // 遍历 state.datas 进行替换
+        for (int i = 0; i < state.datas.length; i++) {
+          if (newItemMap.containsKey(state.datas[i].id)) {
+            state.datas[i] = newItemMap[state.datas[i].id]!;
+          }
+        }
+
+        //刷新
+        update();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  //全部选中
+  void operationSelectAll() {
+    for (var element in state.datas) {
+      element.isSelected = true;
+    }
+    update();
+  }
+
+  /// 筛选状态
+  void pickerStatus() {
+    if (state.jobInfo == null) return;
+
+    int selectedStatusIndex;
+    if (state.selectedStatusId == null) {
+      selectedStatusIndex = 0;
+    } else {
+      selectedStatusIndex = state.jobInfo!.statusList.indexWhere((department) => department.value.toString() == state.selectedStatusId);
+    }
+
+    if (selectedStatusIndex < 0) {
+      selectedStatusIndex = 0;
+    }
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.jobInfo!.statusList.map((e) => e.txt!).toList(growable: false),
+      initialSelectIndex: selectedStatusIndex,
+      onPickerChanged: (_, index) {
+        state.selectedStatusId = state.jobInfo!.statusList[index].value!.toString();
+        state.selectedStatusName = state.jobInfo!.statusList[index].txt!.toString();
+        update();
+        refreshController.callRefresh();
+      },
+    );
+  }
+}

+ 474 - 0
packages/cpt_th/lib/modules/job_er/applied_er/applied_er_item.dart

@@ -0,0 +1,474 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/t_h_applied_index_entity.dart';
+import 'package:domain/entity/response/t_h_applied_table_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_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+/*
+ * 已申请的员工列表Item
+ */
+class AppliedErItem extends StatelessWidget {
+  final int index;
+  final THAppliedIndexEntity? jobInfo;
+  final THAppliedTableRows item;
+  final VoidCallback? onStatusAction;
+  final VoidCallback? onEditAction;
+  final VoidCallback? onRemarkAction;
+  final VoidCallback? onItemAction;
+  final VoidCallback? onMemberAction;
+
+  AppliedErItem({
+    required this.index,
+    required this.item,
+    required this.jobInfo,
+    this.onStatusAction,
+    this.onRemarkAction,
+    this.onEditAction,
+    this.onItemAction,
+    this.onMemberAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          //员工姓名
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Staff Name:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //姓名
+              MyTextView(
+                item.labourerName ?? "-",
+                isFontMedium: true,
+                textColor: ColorConstants.textYellowFFBB1B,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+                textDecoration: TextDecoration.underline,
+                decorationColor: ColorConstants.textYellowFFBB1B,
+                // 可选,设置下划线的颜色
+                decorationThickness: 2.0,
+                // 可选,设置下划线的粗细
+                decorationStyle: TextDecorationStyle.solid,
+                onClick: onMemberAction,
+              ).expanded(),
+
+              //是否选中
+              MyAssetImage(
+                item.isSelected ? Assets.baseServiceItemSelectedIcon : Assets.baseServiceItemUnselectedIcon,
+                width: 20.5,
+                height: 20.5,
+              ),
+            ],
+          ),
+
+          // 服装大小
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Clothing Size".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //姓名
+              MyTextView(
+                item.clothingSize ?? "-",
+                isFontMedium: true,
+                textColor: ColorConstants.textYellowFFBB1B,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+                textDecoration: TextDecoration.underline,
+                decorationColor: ColorConstants.textYellowFFBB1B,
+                // 可选,设置下划线的颜色
+                decorationThickness: 2.0,
+                // 可选,设置下划线的粗细
+                decorationStyle: TextDecorationStyle.solid,
+                onClick: onMemberAction,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 工作开始时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"ID Card No.".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.labourerNric ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // 工作开始时间
+          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
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "+/- Hours:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //小时
+              MyTextView(
+                item.adjustHours ?? "0",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          // Total Hours
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Total Hours:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //小时
+              MyTextView(
+                item.totalHours ?? "0",
+                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: "Completed" == item.statusShow
+                    ? ColorConstants.textGreen05DC82
+                    : "Cancelled" == item.statusShow || "Rejected" == item.statusShow
+                        ? ColorConstants.textRedFF6262
+                        : "Revised" == item.statusShow || "Pending" == item.statusShow || "Approve" == item.statusShow
+                            ? ColorConstants.textYellowFFBB1B
+                            : ColorConstants.textBlue06D9FF, //默认蓝色
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+          //按钮组
+          Visibility(
+            visible: true,
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              mainAxisAlignment: MainAxisAlignment.end,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                //编辑按钮
+                Visibility(
+                  visible: true,
+                  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: true,
+                  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: true,
+                  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();
+      }),
+    );
+  }
+}

+ 255 - 0
packages/cpt_th/lib/modules/job_er/applied_er/applied_er_page.dart

@@ -0,0 +1,255 @@
+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: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_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/search_app_bar.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_er_item.dart';
+import 'applied_er_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 'applied_er_state.dart';
+
+/*
+ * 已申请的页面,可以签到签出、加人、修改状态、评论等操作
+ */
+class AppliedErPage extends BaseStatefulPage<AppliedErController> {
+  AppliedErPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? jobId) {
+    return Get.start(RouterPath.THJobAppliedER, arguments: {'jobId': jobId});
+  }
+
+  @override
+  AppliedErController createRawController() {
+    return AppliedErController();
+  }
+
+  @override
+  State<AppliedErPage> createState() => _JobAppliedState();
+}
+
+class _JobAppliedState extends BaseState<AppliedErPage, AppliedErController> {
+  late AppliedErState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.jobId = Get.arguments['jobId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return SafeArea(
+        bottom: MediaQuery.of(context).padding.bottom > 38,
+        top: false,
+        child: Container(
+          width: double.infinity,
+          height: double.infinity,
+          padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+          decoration: const BoxDecoration(
+            gradient: LinearGradient(
+              colors: [
+                Color(0xFF091D44),
+                Color(0xFF245A8A),
+                Color(0xFF7F7CEC),
+              ],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            ),
+          ),
+          child: Column(
+            children: [
+              MyAppBar.titleBar(
+                context,
+                state.jobInfo?.job?.jobTitle ?? "Title".tr,
+                subTitle: "(${state.jobInfo?.jobDate ?? "-"})",
+                subTitleColor: ColorConstants.textGrayAECAE5,
+              ),
+
+              //搜索的条件
+              Row(
+                children: [
+                  Container(
+                    padding: const EdgeInsets.symmetric(vertical: 7.5, horizontal: 10),
+                    margin: const EdgeInsets.only(left: 0, right: 10),
+                    decoration: BoxDecoration(
+                      color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+                      borderRadius: BorderRadius.circular(20), // 设置圆角
+                    ),
+                    child: Row(
+                      children: [
+                        MyTextView(
+                          state.selectedStatusName ?? "",
+                          hint: "Status".tr,
+                          marginLeft: 10,
+                          textColor: ColorConstants.white,
+                          textHintColor: ColorConstants.textGrayAECAE5,
+                          fontSize: 15,
+                          isFontRegular: true,
+                        ).expanded(),
+                        const MyAssetImage(
+                          Assets.baseServiceTriangleDropDown,
+                          width: 8,
+                          height: 5,
+                        ),
+                      ],
+                    ).onTap(controller.pickerStatus),
+                  ).expanded(),
+                  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 AppliedErItem(
+                          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]);
+                          },
+                          onMemberAction: () {
+                            controller.gotoStaffDetailPage(state.datas[index]);
+                          },
+                        );
+                      },
+                      childCount: state.datas.length,
+                    ))
+                  ],
+                ),
+              ).expanded(),
+
+              Visibility(
+                visible: state.datas.isNotEmpty,
+                child: MyTextView(
+                  "Select All".tr,
+                  fontSize: 17,
+                  isFontMedium: true,
+                  boxHeight: 48,
+                  onClick: () {
+                    controller.operationSelectAll();
+                  },
+                  alignment: Alignment.center,
+                  textAlign: TextAlign.center,
+                  textColor: Colors.white,
+                  backgroundColor: const Color(0XFFCA28E4),
+                ),
+              ),
+
+              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(),
+                ],
+              ),
+            ],
+          ),
+        ),
+      );
+    });
+  }
+}

+ 18 - 0
packages/cpt_th/lib/modules/job_er/applied_er/applied_er_state.dart

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

+ 344 - 0
packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_add_staff.dart

@@ -0,0 +1,344 @@
+import 'dart:ui';
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/job_list_applied_staff_search_entity.dart';
+import 'package:domain/entity/response/t_h_applied_employee_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:widgets/ext/ex_widget.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/search_app_bar.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'er_applied_add_staff_controller.dart';
+
+/*
+ * 添加员工的弹窗
+ */
+class ErAppliedAddStaff extends StatefulWidget {
+  String jobId;
+  void Function(String selectIds)? confirmAction;
+
+  ErAppliedAddStaff({required this.jobId, this.confirmAction});
+
+  @override
+  State<ErAppliedAddStaff> createState() => _AppliedAddStaffState();
+}
+
+class _AppliedAddStaffState extends State<ErAppliedAddStaff> {
+  @override
+  void initState() {
+    super.initState();
+    ErAppliedAddStaffController controller =  Get.put(ErAppliedAddStaffController());
+    controller.jobId = widget.jobId;
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+    Get.delete<ErAppliedAddStaffController>();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return GetBuilder<ErAppliedAddStaffController>(
+      assignId: true,
+      builder: (controller) {
+        return Container(
+          width: 300,
+          height: 555,
+          decoration: const BoxDecoration(
+            color: Color(0XFFF7F7F7),
+            borderRadius: BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Center(
+                child: MyTextView(
+                  "Choose Staff".tr,
+                  fontSize: 19,
+                  isFontMedium: true,
+                  textColor: ColorConstants.black,
+                  marginTop: 22,
+                  marginBottom: 15,
+                  marginLeft: 22,
+                  marginRight: 22,
+                ),
+              ),
+
+              SearchAppBar(
+                value: controller.keyword,
+                searchBarHeight: 38,
+                searchBarBgColor: Colors.white,
+                searchBarBorderRadius: 15,
+                searchBarBorder: Border.all(
+                  color: Color(0XFFC3C3C3), // 设置边框颜色为灰色
+                  width: 0.5, // 设置边框宽度
+                ),
+                textHintColor: Color(0XFFAFB3B7),
+                textColor: ColorConstants.black33,
+                onSearch: (keyword) {
+                  controller.doSearch(keyword);
+                },
+                hintText: "Staff Name/ID/Phone".tr,
+                controller: controller.searchController,
+              ).marginOnly(left: 16.5, right: 1.5, bottom: 15.5),
+
+              Container(
+                color: Colors.white,
+                child: EasyRefresh(
+                  header: ClassicHeader(
+                    dragText: 'Pull to refresh'.tr,
+                    armedText: 'Release ready'.tr,
+                    readyText: 'Refreshing...'.tr,
+                    processingText: 'Refreshing...'.tr,
+                    processedText: 'Succeeded'.tr,
+                    noMoreText: 'No more'.tr,
+                    failedText: 'Failed'.tr,
+                    messageText: 'Last updated at %T'.tr,
+                    textStyle: const TextStyle(color: ColorConstants.black66, fontSize: 14),
+                    messageStyle: const TextStyle(color: ColorConstants.black66, fontSize: 12),
+                    iconTheme: const IconThemeData(color: ColorConstants.black66),
+                    backgroundColor: Colors.transparent,
+                  ),
+                  footer: ClassicFooter(
+                    dragText: 'Pull to load'.tr,
+                    armedText: 'Release ready'.tr,
+                    readyText: 'Loading...'.tr,
+                    processingText: 'Loading...'.tr,
+                    processedText: 'Succeeded'.tr,
+                    noMoreText: 'No more'.tr,
+                    failedText: 'Failed'.tr,
+                    showMessage: false,
+                    triggerOffset: 50,
+                    iconDimension: 22,
+                    textStyle: const TextStyle(color: ColorConstants.black66, fontSize: 14),
+                    messageStyle: const TextStyle(color: ColorConstants.black66, fontSize: 12),
+                    iconTheme: const IconThemeData(color: ColorConstants.black66),
+                    backgroundColor: Colors.transparent,
+                  ),
+                  controller: controller.refreshController,
+                  onRefresh: controller.onRefresh,
+                  onLoad: controller.loadMore,
+                  child: LoadStateLayout(
+                    themeColor: ColorConstants.black66,
+                    state: controller.loadingState,
+                    errorMessage: controller.errorMessage,
+                    errorRetry: () {
+                      controller.retryRequest();
+                    },
+                    successSliverWidget: [
+                      SliverList(
+                          delegate: SliverChildBuilderDelegate(
+                        (context, index) {
+                          return _buildStaffItem(controller.datas[index], () {
+                            /// Item选中与未选中设置
+                            controller.datas[index].isSelected = !controller.datas[index].isSelected;
+                            controller.update();
+                          });
+                        },
+                        childCount: controller.datas.length,
+                      ))
+                    ],
+                  ),
+                ),
+              ).expanded(),
+
+              //按钮组
+              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: () {
+                          doCallbackAction(controller);
+                        },
+                        child: MyTextView(
+                          "Submit".tr,
+                          marginLeft: 10,
+                          fontSize: 17.5,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: Color(0XFF0085C4),
+                          cornerRadius: 3,
+                        ),
+                      )),
+                ],
+              ).constrained(height: 46),
+            ],
+          ),
+        );
+      },
+    );
+  }
+
+  //取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+
+  //执行回调
+  void doCallbackAction(ErAppliedAddStaffController controller) {
+    onCancel();
+
+    //找到当前选中的
+    var selectedList = controller.datas.where((element) => element.isSelected).toList(growable: false);
+    if (selectedList.isNotEmpty) {
+      var ids = selectedList.map((e) => e.id.toString()).toList(growable: false);
+      String separatedIds = ids.join(',');
+
+      widget.confirmAction?.call(separatedIds);
+    }
+
+  }
+
+  Widget _buildStaffItem(THAppliedEmployeeRows item, VoidCallback callback) {
+    return Stack(
+      children: [
+        Column(
+          children: [
+            //姓名
+            Row(
+              children: [
+                MyTextView(
+                  "Staff:",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  marginRight: 3,
+                  isFontRegular: true,
+                ),
+                MyTextView(
+                  item.name ?? "-",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+              ],
+            ),
+
+            //头像
+            Row(
+              children: [
+                MyTextView(
+                  "Avatar:",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  marginRight: 3,
+                  isFontRegular: true,
+                ),
+                MyLoadImage(
+                  item.profilePicture ?? "",
+                  width: 25,
+                  height: 25,
+                ),
+              ],
+            ).marginOnly(top: 5),
+
+            //性别
+            Row(
+              children: [
+                MyTextView(
+                  "Gender:",
+                  marginRight: 3,
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+                MyTextView(
+                  item.gender ?? "-",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+              ],
+            ).marginOnly(top: 5),
+
+            //身份证
+            Row(
+              children: [
+                MyTextView(
+                  "NRIC:",
+                  marginRight: 3,
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+                MyTextView(
+                  item.nric ?? "-",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+              ],
+            ).marginOnly(top: 5),
+
+            //电话
+            Row(
+              children: [
+                MyTextView(
+                  "Phone:",
+                  marginRight: 3,
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+                MyTextView(
+                  item.mobile ?? "-",
+                  textColor: ColorConstants.black66,
+                  fontSize: 13,
+                  isFontRegular: true,
+                ),
+              ],
+            ).marginOnly(top: 5),
+
+            Container(
+              margin: const EdgeInsets.only(top: 19),
+              width: double.infinity,
+              height: 1,
+              color: const Color(0XFFF7F7F7),
+            )
+          ],
+        ).paddingOnly(left: 19, right: 20, top: 17),
+
+        //是否勾选
+        MyAssetImage(
+          item.isSelected ? Assets.baseServiceItemSelectedIcon : Assets.baseServiceItemUnselectedGrayIcon,
+          width: 20.5,
+          height: 20.5,
+        ).alignRight().marginOnly(right: 20, top: 17.5),
+      ],
+    ).onTap(callback);
+  }
+}

+ 130 - 0
packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_add_staff_controller.dart

@@ -0,0 +1,130 @@
+import 'package:domain/entity/response/t_h_applied_employee_entity.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+class ErAppliedAddStaffController extends GetxController with DioCancelableMixin {
+  final THERRepository _erRepository = Get.find();
+
+  TextEditingController searchController = TextEditingController();
+
+  var _curPage = 1;
+  var _needShowPlaceholder = true;
+
+  //页面PlaceHolder的展示
+  LoadState loadingState = LoadState.State_Success;
+  String? errorMessage;
+
+  String keyword = "";
+  String? jobId;
+  List<THAppliedEmployeeRows> datas = [];
+
+  //刷新页面状态
+  void changeLoadingState(LoadState state) {
+    loadingState = state;
+    update();
+  }
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,
+    controlFinishLoad: true,
+  );
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchAllStaffList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchAllStaffList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchAllStaffList();
+  }
+
+  /// 获取列表数据
+  Future fetchAllStaffList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    // 获取 Staff 列表
+    var listResult = await _erRepository.searchStaffList(
+      jobId,
+      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<THAppliedEmployeeRows>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        datas.clear();
+        datas.addAll(list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success);
+      } else {
+        //加载更多
+        datas.addAll(list);
+        refreshController.finishLoad();
+        update();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        datas.clear();
+        changeLoadingState(LoadState.State_Empty);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  //搜索
+  void doSearch(String keyword) {
+    this.keyword = keyword;
+    refreshController.callRefresh();
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchAllStaffList();
+  }
+
+  @override
+  void onClose() {
+    datas.clear();
+    super.onClose();
+  }
+}

+ 241 - 0
packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_butch_modify.dart

@@ -0,0 +1,241 @@
+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 ErAppliedButchModify extends StatefulWidget {
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+  void Function(DateTime startTime, DateTime endTime)? confirmAction;
+
+  ErAppliedButchModify({this.selectedStartDate, this.selectedEndDate, this.confirmAction});
+
+  @override
+  State<ErAppliedButchModify> createState() => _AppliedButchModifyState();
+}
+
+class _AppliedButchModifyState extends State<ErAppliedButchModify> {
+  DateTime? selectedStartDate;
+  DateTime? selectedEndDate;
+
+  @override
+  void initState() {
+    super.initState();
+    selectedStartDate = widget.selectedStartDate;
+    selectedEndDate = widget.selectedEndDate;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        //Title (如果使用 Container 为最外层容器则默认为 match_parent 的效果,除非我们限制宽度和最大高度最小高度)
+        Container(
+          padding: const EdgeInsets.symmetric(horizontal: 16.5),
+          width: double.infinity,
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: 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: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: const BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedStartDate == null ? "" : DateTimeUtils.formatDate(selectedStartDate,format: 'HH:mm'),
+                      fontSize: 14,
+                      hint: "Choose Start Date".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    const 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: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
+                height: 45,
+                decoration: const BoxDecoration(
+                  color: ColorConstants.grayECECEC,
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      selectedEndDate == null ? "" : DateTimeUtils.formatDate(selectedEndDate,format: 'HH:mm'),
+                      fontSize: 14,
+                      hint: "Choose End Date".tr,
+                      textHintColor: ColorConstants.textBlackHint,
+                      isFontMedium: true,
+                      textColor: ColorConstants.black33,
+                    ).expanded(),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                  ],
+                ),
+              ).onTap(() {
+                pickerEndDate();
+              }),
+
+              Container(
+                margin: const EdgeInsets.only(top: 25),
+                color: const 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: const Color(0XFF0085C4),
+                          cornerRadius: 3,
+                        ),
+                      )),
+                ],
+              ).constrained(height: 46),
+            ],
+          ),
+        ),
+      ],
+    ).constrained(width: 285);
+  }
+
+  /// 筛选开始日期
+  void pickerStartDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedStartDate,
+      mode: CupertinoDatePickerMode.time,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedStartDate = date;
+        });
+      },
+      title: "Start Date".tr,
+    );
+  }
+
+  /// 筛选结束日期
+  void pickerEndDate() {
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: selectedEndDate ?? selectedStartDate,
+      mode: CupertinoDatePickerMode.time,
+      onDateTimeChanged: (date) {
+        setState(() {
+          selectedEndDate = date;
+        });
+      },
+      title: "End Date".tr,
+    );
+  }
+
+  //取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

+ 313 - 0
packages/cpt_th/lib/modules/job_er/applied_er/widget/er_applied_staff_reviews.dart

@@ -0,0 +1,313 @@
+import 'dart:ui';
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/job_list_remark_view_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:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/rating_widget.dart';
+import 'package:widgets/widget_export.dart';
+
+/*
+ * 员工的评价弹窗
+ */
+class ErAppliedStaffReviews extends StatefulWidget {
+  JobListRemarkViewEntity appliedReviews;
+  void Function(String attitudeRate, String performanceRate, String experienceRate, String groomingRate, String content)? confirmAction;
+
+  ErAppliedStaffReviews({required this.appliedReviews, this.confirmAction});
+
+  @override
+  State<ErAppliedStaffReviews> createState() => _AppliedStaffReviewsState();
+}
+
+class _AppliedStaffReviewsState extends State<ErAppliedStaffReviews> {
+  late JobListRemarkViewEntity reviews;
+  late String attitudeRate;
+  late String groomingRate;
+  late String performanceRate;
+  late String experienceRate;
+  late String content;
+  late TextEditingController _controller;
+  late FocusNode _focusNode;
+
+  @override
+  void initState() {
+    super.initState();
+    _controller = TextEditingController();
+    _focusNode = FocusNode();
+
+    reviews = widget.appliedReviews;
+    attitudeRate = reviews.attitudeRate.toString();
+    groomingRate = reviews.groomingRate.toString();
+    performanceRate = reviews.performanceRate.toString();
+    experienceRate = reviews.experienceRate.toString();
+    _controller.text = reviews.feedback ?? "";
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        //Title (如果使用 Container 为最外层容器则默认为 match_parent 的效果,除非我们限制宽度和最大高度最小高度)
+        Container(
+          width: double.infinity,
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Center(
+                child: MyTextView(
+                  "Remarks".tr,
+                  fontSize: 19,
+                  isFontMedium: true,
+                  textColor: ColorConstants.black,
+                  marginTop: 23,
+                  marginBottom: 19,
+                  marginLeft: 22,
+                  marginRight: 22,
+                ),
+              ),
+
+              MyTextView(
+                reviews.labourerName ?? "",
+                isFontRegular: true,
+                textColor: Colors.black,
+                marginLeft: 22,
+                marginRight: 22,
+                fontSize: 17,
+              ),
+
+              //态度评分
+              Row(
+                children: [
+                  MyTextView(
+                    "Attitude".tr,
+                    isFontRegular: true,
+                    textColor: ColorConstants.black66,
+                    fontSize: 15,
+                  ).expanded(),
+                  RatingWidget(
+                    nomalImage: Assets.baseServiceRatingUnselected,
+                    selectImage: Assets.baseServiceRatingSelected,
+                    size: 21,
+                    padding: 5,
+                    selectAble: Utils.isEmpty(reviews.content),
+                    integerOnly: true,
+                    value: reviews.attitudeRate,
+                    onRatingUpdate: (value) {
+                      attitudeRate = value;
+                    },
+                  )
+                ],
+              ).marginOnly(top: 15, left: 22, right: 22),
+
+              //表现评分
+              Row(
+                children: [
+                  MyTextView(
+                    "Performance".tr,
+                    isFontRegular: true,
+                    textColor: ColorConstants.black66,
+                    fontSize: 15,
+                  ).expanded(),
+                  RatingWidget(
+                    nomalImage: Assets.baseServiceRatingUnselected,
+                    selectImage: Assets.baseServiceRatingSelected,
+                    size: 21,
+                    padding: 5,
+                    selectAble: Utils.isEmpty(reviews.content),
+                    integerOnly: true,
+                    value: reviews.performanceRate,
+                    onRatingUpdate: (value) {
+                      performanceRate = value;
+                    },
+                  )
+                ],
+              ).marginOnly(top: 15, left: 22, right: 22),
+
+              //经验评分
+              Row(
+                children: [
+                  MyTextView(
+                    "Experience".tr,
+                    isFontRegular: true,
+                    textColor: ColorConstants.black66,
+                    fontSize: 15,
+                  ).expanded(),
+                  RatingWidget(
+                    nomalImage: Assets.baseServiceRatingUnselected,
+                    selectImage: Assets.baseServiceRatingSelected,
+                    size: 21,
+                    padding: 5,
+                    selectAble: Utils.isEmpty(reviews.content),
+                    integerOnly: true,
+                    value: reviews.experienceRate,
+                    onRatingUpdate: (value) {
+                      experienceRate = value;
+                    },
+                  )
+                ],
+              ).marginOnly(top: 15, left: 22, right: 22),
+
+              //着装评分
+              Row(
+                children: [
+                  MyTextView(
+                    "Grooming".tr,
+                    isFontRegular: true,
+                    textColor: ColorConstants.black66,
+                    fontSize: 15,
+                  ).expanded(),
+                  RatingWidget(
+                    nomalImage: Assets.baseServiceRatingUnselected,
+                    selectImage: Assets.baseServiceRatingSelected,
+                    size: 21,
+                    padding: 5,
+                    selectAble: Utils.isEmpty(reviews.content),
+                    integerOnly: true,
+                    value: reviews.groomingRate,
+                    onRatingUpdate: (value) {
+                      groomingRate = value;
+                    },
+                  )
+                ],
+              ).marginOnly(top: 15, left: 22, right: 22),
+
+              IgnoreKeyboardDismiss(
+                child: Container(
+                  height: 130,
+                  margin: const EdgeInsets.symmetric(vertical: 19, horizontal: 22),
+                  padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                  decoration: BoxDecoration(
+                    color: const Color(0xFFF0F0F0),
+                    border: Border.all(
+                      color: const Color(0xFFD8D8D8),
+                      width: 0.5,
+                    ),
+                  ),
+                  child: TextField(
+                    cursorColor: ColorConstants.black66,
+                    cursorWidth: 1.5,
+                    autofocus: false,
+                    enabled: Utils.isEmpty(reviews.content),
+                    focusNode: _focusNode,
+                    controller: _controller,
+                    // 装饰
+                    decoration: InputDecoration(
+                      isDense: true,
+                      isCollapsed: true,
+                      border: InputBorder.none,
+                      hintText: "Enter...".tr,
+                      hintStyle: const TextStyle(
+                        color: ColorConstants.black66,
+                        fontSize: 15.0,
+                        fontWeight: FontWeight.w400,
+                      ),
+                    ),
+                    style: const TextStyle(
+                      color: ColorConstants.black,
+                      fontSize: 15.0,
+                      fontWeight: FontWeight.w400,
+                    ),
+                    // 键盘动作右下角图标
+                    textInputAction: TextInputAction.done,
+                    onSubmitted: (value) {
+                      doCallbackAction();
+                    },
+                  ),
+                ),
+              ),
+
+              // 分割线
+              Container(
+                color: const 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: () {
+                          doCallbackAction();
+                        },
+                        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 onCancel() async {
+    SmartDialog.dismiss();
+  }
+
+  //执行回调
+  void doCallbackAction() {
+    _focusNode.unfocus();
+
+    content = _controller.text.toString();
+
+    if (attitudeRate == "0" || experienceRate == "0" || performanceRate == "0" || groomingRate == "0") {
+      ToastEngine.show("Rate First");
+      return;
+    }
+
+    if (Utils.isEmpty(content)) {
+      ToastEngine.show("Please Enter Remark".tr);
+      return;
+    }
+
+    onCancel();
+
+    widget.confirmAction?.call(attitudeRate, performanceRate, experienceRate, groomingRate, content);
+  }
+}

+ 195 - 0
packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_controller.dart

@@ -0,0 +1,195 @@
+import 'package:domain/repository/job_repository.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:get/get.dart';
+import 'package:plugin_basic/constants/app_constant.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/event_bus.dart';
+import 'package:widgets/picker/date_picker_util.dart';
+
+import 'applied_er_edit_state.dart';
+
+class AppliedErEditController extends GetxController with DioCancelableMixin {
+  final THERRepository _erRepository = Get.find();
+  final AppliedErEditState state = AppliedErEditState();
+
+  // 获取编辑的详情
+  void fetchAppliedEditView() async {
+    var result = await _erRepository.fetchERAppliedEditDetail(appliedId: state.appliedId, cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      state.appliedEditView = result.data;
+
+      var addHourController = state.formData['add_hours']!['controller'];
+      var totalRoomController = state.formData['total_room']!['controller'];
+      var reasonController = state.formData['reason']!['controller'];
+
+      addHourController.text = state.appliedEditView?.subtractHours ?? "0";
+      // totalRoomController.text = state.appliedEditView?.totalRooms.toString();
+      reasonController.text = state.appliedEditView?.remark ?? "";
+
+      state.selectedReasonType = state.appliedEditView?.applied?.reasonType;
+      state.selectedStatusId = state.appliedEditView?.applied?.status;
+
+      update();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+      return;
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchAppliedEditView();
+  }
+
+  /// 选择时间
+  void pickStartTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTimeByMs((state.appliedEditView?.applied?.startTime ?? 0) * 1000),
+      mode: CupertinoDatePickerMode.time,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.startTime = DateTimeUtils.formatDate(date, format: 'HH:mm:ss');
+        update();
+      },
+      title: "Start Time".tr,
+    );
+  }
+
+  /// 选择时间
+  void pickEndTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTimeByMs((state.appliedEditView?.applied?.endTime ?? 0) * 1000),
+      mode: CupertinoDatePickerMode.time,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.endTime = DateTimeUtils.formatDate(date, format: 'HH:mm:ss');
+        update();
+      },
+      title: "End Time".tr,
+    );
+  }
+
+  /// 选择时间
+  void pickSecurityInTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTime(state.appliedEditView!.securityIn ?? ""),
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.securityIn = DateTimeUtils.formatDate(date);
+        update();
+      },
+      title: "Security In".tr,
+    );
+  }
+
+  /// 选择时间
+  void pickSecurityOutTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTime(state.appliedEditView!.securityOut ?? ""),
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.securityOut = DateTimeUtils.formatDate(date);
+        update();
+      },
+      title: "Security Out".tr,
+    );
+  }
+
+  /// 选择时间
+  void pickWorkInTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTime(state.appliedEditView!.workIn ?? ""),
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.workIn = DateTimeUtils.formatDate(date);
+        update();
+      },
+      title: "Work In".tr,
+    );
+  }
+
+  /// 选择时间
+  void pickWorkOutTime() {
+    if (state.appliedEditView == null) return;
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: DateTimeUtils.getDateTime(state.appliedEditView!.workOut ?? ""),
+      mode: CupertinoDatePickerMode.dateAndTime,
+      onDateTimeChanged: (date) {
+        state.appliedEditView!.workOut = DateTimeUtils.formatDate(date);
+        update();
+      },
+      title: "Work Out".tr,
+    );
+  }
+
+  /// 提交修改
+  void doSubmit() async {
+    if (state.appliedEditView == null) return;
+
+    //输入框的数据赋值
+    // TextEditingController totalRoomController = state.formData['total_room']!['controller'];
+    TextEditingController addHourController = state.formData['add_hours']!['controller'];
+    TextEditingController reasonController = state.formData['reason']!['controller'];
+    // 获取文本并尝试转换为整数
+    // String totalRoomText = totalRoomController.text;
+    // if (totalRoomText.isNotEmpty) {
+    //   try {
+    //     // 尝试将文本转换为整数
+    //     int totalRooms = int.parse(totalRoomText);
+    //     // 赋值给 state.appliedEditView!.totalRooms
+    //     state.appliedEditView!.totalRooms = totalRooms;
+    //   } catch (e) {
+    //     // 如果转换失败,可以进行错误处理
+    //     print('Error parsing totalRooms: $e');
+    //   }
+    // } else {
+    //   // 文本为空时的处理逻辑,例如设置默认值或提示用户
+    //   print('Total rooms input is empty');
+    // }
+
+    state.appliedEditView!.subtractHours = addHourController.text.toString();
+    state.appliedEditView!.remark = reasonController.text.toString();
+
+    //请求网络提交修改
+    var result = await _erRepository.editAppliedDetailSubmit(
+      appliedId: state.appliedId,
+      startTime: state.appliedEditView?.startTime,
+      endTime: state.appliedEditView?.endTime,
+      securityIn: state.appliedEditView?.securityIn,
+      securityOut: state.appliedEditView?.securityOut,
+      workIn: state.appliedEditView?.workIn,
+      workOut: state.appliedEditView?.workOut,
+      subtractHours: state.appliedEditView?.subtractHours,
+      reasonType: state.selectedReasonType,
+      status: state.selectedStatusId,
+      remark: state.appliedEditView?.remark,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      bus.emit(AppConstant.eventAppliedListRefresh, state.appliedId);
+
+      Get.back();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+      return;
+    }
+  }
+}

+ 564 - 0
packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_page.dart

@@ -0,0 +1,564 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:get/get.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/no_shadow_scroll_behavior.dart';
+import 'package:widgets/shatter/custom_radio_check.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/round_my_text_field.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_er_edit_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 'applied_er_edit_state.dart';
+
+/*
+ * Applied列表中,编辑用户的此次工作打卡信息
+ */
+class AppliedErEditPage extends BaseStatefulPage<AppliedErEditController> {
+  AppliedErEditPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? appliedId) {
+    return Get.start(RouterPath.THJobAppliedEditER, arguments: {'appliedId': appliedId});
+  }
+
+  @override
+  AppliedErEditController createRawController() {
+    return AppliedErEditController();
+  }
+
+  @override
+  State<AppliedErEditPage> createState() => _JobAppliedEditState();
+}
+
+class _JobAppliedEditState extends BaseState<AppliedErEditPage, AppliedErEditController> {
+  late AppliedErEditState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.appliedId = Get.arguments['appliedId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appBar(context, "Edit".tr),
+        body: SafeArea(
+          bottom: MediaQuery.of(context).padding.bottom > 38,
+          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: [
+                      MyTextView(
+                        "Job Date".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //工作时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.5),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.applied?.jobDate ?? "-",
+                              fontSize: 15,
+                              hint: "Choose Job Title".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //工作标题,选择模板
+                      MyTextView(
+                        "Staff Name".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //工作标题
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.5),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.applied?.labourerName ?? "-",
+                              fontSize: 15,
+                              hint: "Choose Job Title".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                          ],
+                        ),
+                      ),
+
+                      //开始时间
+                      FormRequireText(
+                        text: "Start Time".tr,
+                      ).marginOnly(top: 15),
+
+                      //选择时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.startTime ?? "-",
+                              fontSize: 14,
+                              hint: "Job Start Time".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickStartTime();
+                      }),
+
+                      //门卫签到时间
+                      MyTextView(
+                        "Security In".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //门卫签到时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.securityIn ?? "-",
+                              fontSize: 14,
+                              hint: "Security In".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickSecurityInTime();
+                      }),
+
+                      //工作地签到时间
+                      MyTextView(
+                        "Work In".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //工作地签到时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.workIn ?? "-",
+                              fontSize: 14,
+                              hint: "Work In".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickWorkInTime();
+                      }),
+
+                      //结束时间
+                      FormRequireText(
+                        text: "End Time".tr,
+                      ).marginOnly(top: 15),
+
+                      //结束时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.endTime ?? "-",
+                              fontSize: 14,
+                              hint: "Job End Time".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickEndTime();
+                      }),
+
+                      //门卫签出时间
+                      MyTextView(
+                        "Security Out".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //门卫签出时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.securityOut ?? "-",
+                              fontSize: 14,
+                              hint: "Security Out".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickSecurityOutTime();
+                      }),
+
+                      //工作地签出时间
+                      MyTextView(
+                        "Work Out".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //工作地签出时间
+                      Container(
+                        padding: const EdgeInsets.only(left: 16, right: 10),
+                        margin: const EdgeInsets.only(top: 10),
+                        height: 45,
+                        decoration: BoxDecoration(
+                          color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                          borderRadius: const BorderRadius.all(Radius.circular(5)),
+                        ),
+                        child: Row(
+                          mainAxisSize: MainAxisSize.max,
+                          crossAxisAlignment: CrossAxisAlignment.center,
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          children: [
+                            MyTextView(
+                              state.appliedEditView?.workOut ?? "-",
+                              fontSize: 14,
+                              hint: "Work Out".tr,
+                              textHintColor: ColorConstants.textGrayAECAE5,
+                              isFontMedium: true,
+                              textColor: ColorConstants.white,
+                            ).expanded(),
+                            //下拉选图标
+                            const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          ],
+                        ),
+                      ).onTap(() {
+                        FocusScope.of(context).unfocus();
+                        controller.pickWorkOutTime();
+                      }),
+
+                      // + - 小时
+                      MyTextView(
+                        "Subtract Hours".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //+ - 小时输入框
+                      CustomTextField(
+                        formKey: "add_hours",
+                        marginLeft: 0,
+                        marginRight: 0,
+                        paddingTop: 0,
+                        paddingBottom: 0,
+                        height: 45,
+                        fillBackgroundColor: const Color(0xFF4DCFF6).withOpacity(0.2),
+                        enabled: true,
+                        textInputType: TextInputType.number,
+                        formData: state.formData,
+                        textInputAction: TextInputAction.done,
+                        onSubmit: (key, value) {
+                          FocusScope.of(context).unfocus();
+                        },
+                        marginTop: 10,
+                      ),
+
+                      // // 房间计费,房间数量
+                      // Visibility(
+                      //   visible: state.appliedEditView?.jobUnit != "hour",
+                      //   child: MyTextView(
+                      //     "Total Rooms".tr,
+                      //     textColor: Colors.white,
+                      //     fontSize: 15,
+                      //     marginTop: 15,
+                      //     isFontRegular: true,
+                      //   ),
+                      // ),
+                      //
+                      // // 房间计费,房间数量输入框
+                      // Visibility(
+                      //   visible: state.appliedEditView?.jobUnit != "hour",
+                      //   child: CustomTextField(
+                      //     formKey: "total_room",
+                      //     marginLeft: 0,
+                      //     marginRight: 0,
+                      //     paddingTop: 0,
+                      //     paddingBottom: 0,
+                      //     height: 45,
+                      //     fillBackgroundColor: const Color(0xFF4DCFF6).withOpacity(0.2),
+                      //     enabled: true,
+                      //     inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
+                      //     textInputType: TextInputType.number,
+                      //     formData: state.formData,
+                      //     textInputAction: TextInputAction.done,
+                      //     onSubmit: (key, value) {
+                      //       FocusScope.of(context).unfocus();
+                      //     },
+                      //     marginTop: 10,
+                      //   ),
+                      // ),
+
+                      // 状态
+                      MyTextView(
+                        "Status".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //状态的单选
+                      state.appliedEditView != null
+                          ? CustomRadioCheck(
+                        options: state.appliedEditView!.statusList.map((e) => e.txt).whereType<String>().toList(),
+                        selectedPosition: state.appliedEditView!.statusList.indexWhere((element) => element.value == state.appliedEditView?.applied?.status),
+                        onOptionSelected: (index, text) {
+                          //修改内存的值
+                          state.selectedStatusId = state.appliedEditView!.statusList[index].value;
+                        },
+                      ).marginOnly(top: 15)
+                          : const CircularProgressIndicator(),
+
+                      // 修改的理由
+                      MyTextView(
+                        "Reason".tr,
+                        textColor: Colors.white,
+                        fontSize: 15,
+                        marginTop: 15,
+                        isFontRegular: true,
+                      ),
+
+                      //理由的单选
+                      state.appliedEditView != null
+                          ? CustomRadioCheck(
+                              options: state.appliedEditView!.reasonList.map((e) => e.txt).whereType<String>().toList(), //后台返回的数据展示,并且根据后台的数据匹配索引
+                              selectedPosition: state.appliedEditView!.reasonList.indexWhere((element) => element.value == state.appliedEditView?.applied?.reasonType),
+                              onOptionSelected: (index, text) {
+                                //修改内存的值
+                                state.selectedReasonType = state.appliedEditView!.reasonList[index].value;
+                              },
+                            ).marginOnly(top: 15, bottom: 20)
+                          : const CircularProgressIndicator(),
+
+                      IgnoreKeyboardDismiss(
+                        child: Container(
+                          height: 130,
+                          padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                          decoration: BoxDecoration(
+                            color: const Color(0xFF4DCFF6).withOpacity(0.2),
+                            borderRadius: const BorderRadius.all(Radius.circular(5)),
+                          ),
+                          child: TextField(
+                            cursorColor: ColorConstants.white,
+                            cursorWidth: 1.5,
+                            autofocus: false,
+                            controller: state.formData["reason"]!['controller'],
+                            focusNode: state.formData["reason"]!['focusNode'],
+                            obscureText: state.formData["reason"]!['obsecure'],
+                            // 装饰
+                            decoration: InputDecoration(
+                              isDense: true,
+                              isCollapsed: true,
+                              border: InputBorder.none,
+                              hintText: state.formData["reason"]!['hintText'],
+                              hintStyle: const TextStyle(
+                                color: ColorConstants.white,
+                                fontSize: 15.0,
+                                fontWeight: FontWeight.w400,
+                              ),
+                            ),
+                            style: const TextStyle(
+                              color: ColorConstants.white,
+                              fontSize: 15.0,
+                              fontWeight: FontWeight.w400,
+                            ),
+                            // 键盘动作右下角图标
+                            textInputAction: TextInputAction.done,
+                            onSubmitted: (value) {
+                              FocusScope.of(context).unfocus();
+                            },
+                          ),
+                        ),
+                      ),
+
+                      //提交按钮
+                      MyButton(
+                        type: ClickType.throttle,
+                        milliseconds: 500,
+                        onPressed: () {
+                          FocusScope.of(context).unfocus();
+                          controller.doSubmit();
+                        },
+                        text: "Submit".tr,
+                        textColor: ColorConstants.white,
+                        fontSize: 16,
+                        radius: 22.5,
+                        backgroundColor: hexToColor("#FFBB1B"),
+                        fontWeight: FontWeight.w500,
+                      ).marginSymmetric(horizontal: 0, vertical: 30),
+                    ],
+                  ).paddingOnly(left: 15, right: 15),
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 44 - 0
packages/cpt_th/lib/modules/job_er/applied_er_edit/applied_er_edit_state.dart

@@ -0,0 +1,44 @@
+import 'package:domain/entity/response/job_list_applied_edit_entity.dart';
+import 'package:domain/entity/response/t_h_applied_edit_entity.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
+
+class AppliedErEditState {
+  //表单的校验与数据
+  Map<String, Map<String, dynamic>> formData = {
+    'add_hours': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': '0',
+      'obsecure': false,
+    },
+    'total_room': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': '0',
+      'obsecure': false,
+    },
+    'reason': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter...'.tr,
+      'obsecure': false,
+    },
+  };
+
+  THAppliedEditEntity? appliedEditView;
+
+  String? appliedId;
+
+  //功能选项
+  final editOption = ['None'.tr, 'Forgot to clock in/out'.tr, 'Technical issue'.tr, 'Others'.tr];
+
+  //选项默认选中索引为0
+  int editOptionPosition = 0;
+
+  String? selectedReasonType;
+  String? selectedStatusId;
+}

+ 162 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_controller.dart

@@ -0,0 +1,162 @@
+import 'package:domain/entity/response/staff_labour_history_entity.dart';
+import 'package:domain/entity/response/t_h_employee_detail_entity.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/engine/loading/loading_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../applied_er_staff_reviews/applied_er_staff_reviews_page.dart';
+import 'applied_er_staff_detail_state.dart';
+
+class AppliedErStaffDetailController extends GetxController with DioCancelableMixin {
+  final THERRepository _erRepository = Get.find();
+  final AppliedErStaffDetailState state = AppliedErStaffDetailState();
+
+  var _curPage = 1;
+  var _isSearch = false;
+  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;
+    fetchStaffDetail();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchStaffDetail();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchStaffDetail();
+  }
+
+  /// 获取列表数据
+  Future fetchStaffDetail() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    } else if (_isSearch) {
+      LoadingEngine.show();
+    }
+
+    // 并发执行两个请求
+    var futures = [
+      _erRepository.fetchStaffLabourHistory(
+        state.memberId,
+        state.keyword,
+        curPage: _curPage,
+        cancelToken: cancelToken,
+      ),
+      state.detail == null
+          ? _erRepository.fetchStaffDetail(state.memberId, cancelToken: cancelToken)
+          : Future(() => HttpResult(isSuccess: true).convert(data: state.detail!)),
+    ];
+
+    //拿到结果
+    var results = await Future.wait(futures);
+    var listResult = results[0] as HttpResult<StaffLabourHistoryEntity>;
+    var detailResult = results[1] as HttpResult<THEmployeeDetailEntity>;
+
+    //详情数据
+    if (state.detail == null && detailResult.isSuccess) {
+      state.detail = detailResult.data!;
+    }
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.rows);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    _isSearch = false;
+    LoadingEngine.dismiss();
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<StaffLabourHistoryRows>? 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();
+    _isSearch = true;
+    onRefresh();
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchStaffDetail();
+  }
+
+  @override
+  void onClose() {
+    super.onClose();
+  }
+
+  // 去员工的评论列表页面
+  void gotoRemarkHistoryPage() {
+    AppliedErStaffReviewsPage.startInstance(
+      state.memberId,
+      state.detail?.workerName,
+      double.parse(state.detail?.reviews?.avgScore ?? "0"),
+      state.detail?.reviews?.count,
+    );
+  }
+}

+ 138 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_page.dart

@@ -0,0 +1,138 @@
+import 'package:cs_resources/constants/color_constants.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_text_view.dart';
+import 'package:widgets/search_app_bar.dart';
+import 'package:widgets/widget_export.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 'applied_er_staff_detail_controller.dart';
+import 'applied_er_staff_detail_state.dart';
+import 'staff_detail_widget.dart';
+import 'staff_labour_history_item.dart';
+
+class AppliedErStaffDetailPage extends BaseStatefulPage<AppliedErStaffDetailController> {
+  AppliedErStaffDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? memberId) {
+    return Get.start(RouterPath.THJobAppliedEmployeeER, arguments: {'memberId': memberId});
+  }
+
+  @override
+  AppliedErStaffDetailController createRawController() {
+    return AppliedErStaffDetailController();
+  }
+
+  @override
+  State<AppliedErStaffDetailPage> createState() => _AppliedStaffDetailState();
+}
+
+class _AppliedStaffDetailState extends BaseState<AppliedErStaffDetailPage, AppliedErStaffDetailController> {
+  late AppliedErStaffDetailState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.memberId = Get.arguments['memberId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return SafeArea(
+        bottom: MediaQuery.of(context).padding.bottom > 38,
+          top: false,
+          child: Container(
+            width: double.infinity,
+            height: double.infinity,
+            padding: EdgeInsets.only(top:ScreenUtil.getStatusBarH(context)),
+            decoration: const BoxDecoration(
+              gradient: LinearGradient(
+                colors: [
+                  Color(0xFF091D44),
+                  Color(0xFF245A8A),
+                  Color(0xFF7F7CEC),
+                ],
+                begin: Alignment.topCenter,
+                end: Alignment.bottomCenter,
+              ),
+            ),
+            child: Column(
+              children: [
+                MyAppBar.titleBar(context, "Staff Detail".tr),
+
+                EasyRefresh(
+                  controller: controller.refreshController,
+                  onRefresh: controller.onRefresh,
+                  onLoad: controller.loadMore,
+                  child: LoadStateLayout(
+                    state: controller.loadingState,
+                    errorMessage: controller.errorMessage,
+                    errorRetry: () {
+                      controller.retryRequest();
+                    },
+                    successSliverWidget: [
+                      //顶部用户信息
+                      SliverToBoxAdapter(
+                        child: StaffDetailWidget(detail: state.detail,onRemarkAction: (){
+                          controller.gotoRemarkHistoryPage();
+                        }),
+                      ),
+
+                      //中间搜索布局
+                      SliverToBoxAdapter(
+                        child: _buildSearchWidget(),
+                      ),
+
+                      //底部工作历史列表
+                      SliverList(
+                          delegate: SliverChildBuilderDelegate(
+                        (context, index) {
+                          return StaffLabourHistoryItem(index: index, item: state.datas[index]);
+                        },
+                        childCount: state.datas.length,
+                      ))
+                    ],
+                  ),
+                ).marginOnly(top: 5,bottom: 5).expanded(),
+              ],
+            ),
+          ),
+        );
+    });
+  }
+
+  // 搜索的布局
+  Widget _buildSearchWidget() {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        MyTextView(
+          "Job History",
+          marginLeft: 15,
+          marginTop: 10,
+          fontSize: 17,
+          textColor: ColorConstants.white,
+          isFontMedium: true,
+        ),
+        SearchAppBar(
+          value: state.keyword,
+          searchBarHeight: 38,
+          onSearch: (keyword) {
+            controller.doSearch(keyword);
+          },
+          hintText: "Job Title".tr,
+        ).marginOnly(left: 16.5, right: 1.5, bottom: 10, top: 10),
+      ],
+    );
+  }
+}

+ 15 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/applied_er_staff_detail_state.dart

@@ -0,0 +1,15 @@
+import 'package:domain/entity/response/staff_labour_history_entity.dart';
+import 'package:domain/entity/response/t_h_employee_detail_entity.dart';
+import 'package:flutter/cupertino.dart';
+
+class AppliedErStaffDetailState {
+
+  TextEditingController? searchController;
+
+  String? memberId;
+  String keyword = "";
+
+  THEmployeeDetailEntity? detail;
+  List<StaffLabourHistoryRows> datas = [];
+
+}

+ 292 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/staff_detail_widget.dart

@@ -0,0 +1,292 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/staff_detail_entity.dart';
+import 'package:domain/entity/response/t_h_employee_detail_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:plugin_platform/engine/image/image_preview.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+/*
+ * 员工的信息
+ */
+class StaffDetailWidget extends StatelessWidget {
+  final THEmployeeDetailEntity? detail;
+  final void Function() onRemarkAction;
+
+  StaffDetailWidget({
+    required this.detail,
+    required this.onRemarkAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 10),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          //头像
+          Center(
+              child: Hero(
+            tag: '112cc8a34e13',
+            child: MyLoadImage(
+              detail?.icon ?? "",
+              width: 100,
+              height: 100,
+            ),
+          )).onTap(() {
+            if (Utils.isNotEmpty(detail?.icon)) {
+              ImagePreviewEngine.singleImagePreview(context, detail!.icon!, heroTag: '112cc8a34e13');
+            }
+          }).marginOnly(top: 25, bottom: 15),
+
+          //姓名
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Name:".tr,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.workerName ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22),
+
+          //性别
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "${"Gender".tr}:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.sex ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //电话
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Mobile:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.staff?.mobile ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //身份证
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "${"ID Card No.".tr}:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.staff?.nric ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //评分
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "${"Reviews".tr}:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                "${detail?.reviews?.avgScore ?? "-"} (${detail?.reviews?.count ?? "0"} Reviews)",
+                marginLeft: 5,
+                textColor: ColorConstants.textGreen0AC074,
+                fontSize: 14,
+                onClick: onRemarkAction,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //时薪
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "${"Hourly Rate".tr}:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.hourlyRate ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //Typhoid
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Typhoid:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.staff?.typhoidDate ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //Food hy
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Food hy:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.staff?.foodHygiene ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //Criminal check:
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Criminal check:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                Utils.isNotEmpty(detail?.staff?.criminalFile) ? "criminal check file" : "",
+                marginLeft: 5,
+                textColor: ColorConstants.textYellowFFBB1B,
+                textDecoration: TextDecoration.underline,
+                decorationColor: ColorConstants.textYellowFFBB1B,
+                decorationThickness: 2.0,
+                decorationStyle: TextDecorationStyle.solid,
+                fontSize: 14,
+                onClick: () {
+                  if (Utils.isNotEmpty(detail?.staff?.criminalFile)) {
+                    ImagePreviewEngine.singleImagePreview(context, detail!.staff!.criminalFile!);
+                  }
+                },
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //Criminal check time:
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Criminal check time:",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.staff?.criminalDate ?? "-",
+                marginLeft: 5,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10),
+
+          //紧急联系人电话
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyTextView(
+                "Clothing Size: ",
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+                isFontRegular: true,
+              ),
+              MyTextView(
+                detail?.clothingSize ?? "-",
+                isFontMedium: true,
+                textColor: ColorConstants.textYellowFFBB1B,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+                textDecoration: TextDecoration.underline,
+                decorationColor: ColorConstants.textYellowFFBB1B,
+                // 可选,设置下划线的颜色
+                decorationThickness: 2.0,
+                // 可选,设置下划线的粗细
+                decorationStyle: TextDecorationStyle.solid,
+              ).expanded(),
+            ],
+          ).marginOnly(left: 22, right: 22, top: 10, bottom: 26),
+        ],
+      ),
+    );
+  }
+}

+ 215 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_detail/staff_labour_history_item.dart

@@ -0,0 +1,215 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/staff_labour_history_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_text_view.dart';
+
+/*
+ * 员工的做工记录
+ */
+class StaffLabourHistoryItem extends StatelessWidget {
+  final int index;
+  final StaffLabourHistoryRows item;
+
+  StaffLabourHistoryItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          //工作日期
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Job Date".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //日期
+              MyTextView(
+                item.jobDate ?? "-",
+                isFontRegular: true,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+              ).expanded(),
+
+            ],
+          ),
+
+          // 工作开始时间
+          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(
+                "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(
+                "${"Employer".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //标题
+              MyTextView(
+                item.employerName ?? "-",
+                isFontRegular: true,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+              ).expanded(),
+
+            ],
+          ).marginOnly(top: 12),
+
+          //工作标题(模板)
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Job Title:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //标题
+              MyTextView(
+                item.jobTitle ?? "-",
+                isFontRegular: true,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+              ).expanded(),
+
+            ],
+          ).marginOnly(top: 12),
+
+          //部门
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Outlet:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //部门
+              MyTextView(
+                item.outletName ?? "-",
+                isFontRegular: true,
+                textColor: ColorConstants.white,
+                fontSize: 14,
+                marginLeft: 5,
+                marginRight: 5,
+              ).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: "Completed" == item.statusShow
+                    ? ColorConstants.textGreen05DC82
+                    : "Cancelled" == item.statusShow || "Rejected" == item.statusShow
+                        ? ColorConstants.textRedFF6262
+                        : "Revised" == item.statusShow || "Pending" == item.statusShow || "Approve" == item.statusShow
+                            ? ColorConstants.textYellowFFBB1B
+                            : ColorConstants.textBlue06D9FF,  //默认蓝色
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 12),
+
+        ],
+      ),
+    );
+  }
+}

+ 108 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_controller.dart

@@ -0,0 +1,108 @@
+import 'package:domain/entity/response/t_h_employee_remarks_entity.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_er_staff_reviews_state.dart';
+
+class AppliedErStaffReviewsController extends GetxController with DioCancelableMixin {
+  final THERRepository _erRepository = Get.find();
+  final AppliedErStaffReviewsState state = AppliedErStaffReviewsState();
+
+  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;
+    fetchStaffReviews();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchStaffReviews();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchStaffReviews();
+  }
+
+  /// 获取列表数据
+  Future fetchStaffReviews() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    var listResult = await _erRepository.fetchStaffRemarkHistory(state.memberId, curPage: _curPage, cancelToken: cancelToken);
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.reviews);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<THEmployeeRemarksReviews>? 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();
+    fetchStaffReviews();
+  }
+}

+ 162 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_page.dart

@@ -0,0 +1,162 @@
+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:widgets/ext/ex_widget.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/rating_widget.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_er_staff_reviews_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 'applied_staff_reviews_item.dart';
+import 'applied_er_staff_reviews_state.dart';
+
+/*
+ * 员工的评论页面
+ */
+class AppliedErStaffReviewsPage extends BaseStatefulPage<AppliedErStaffReviewsController> {
+  AppliedErStaffReviewsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? memberId, String? staffName, double? reviews, String? reviewCount) {
+    return Get.start(
+      RouterPath.THJobAppliedEmployeeRemarkER,
+      arguments: {'memberId': memberId, 'staffName': staffName, 'reviews': reviews, 'reviewCount': reviewCount},
+    );
+  }
+
+  @override
+  AppliedErStaffReviewsController createRawController() {
+    return AppliedErStaffReviewsController();
+  }
+
+  @override
+  State<AppliedErStaffReviewsPage> createState() => _AppliedStaffReviewsState();
+}
+
+class _AppliedStaffReviewsState extends BaseState<AppliedErStaffReviewsPage, AppliedErStaffReviewsController> {
+  late AppliedErStaffReviewsState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.memberId = Get.arguments['memberId'];
+    state.staffName = Get.arguments['staffName'];
+    state.reviews = Get.arguments['reviews'];
+    state.reviewCount = Get.arguments['reviewCount'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return SafeArea(
+        bottom: MediaQuery.of(context).padding.bottom > 38,
+        top: false,
+        child: Container(
+          width: double.infinity,
+          height: double.infinity,
+          padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+          decoration: const BoxDecoration(
+            gradient: LinearGradient(
+              colors: [
+                Color(0xFF091D44),
+                Color(0xFF245A8A),
+                Color(0xFF7F7CEC),
+              ],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            ),
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            mainAxisSize: MainAxisSize.max,
+            children: [
+              MyAppBar.titleBar(context, "Staff Detail".tr),
+              EasyRefresh(
+                controller: controller.refreshController,
+                onRefresh: controller.onRefresh,
+                onLoad: controller.loadMore,
+                child: LoadStateLayout(
+                  state: controller.loadingState,
+                  errorMessage: controller.errorMessage,
+                  errorRetry: () {
+                    controller.retryRequest();
+                  },
+                  successSliverWidget: [
+                    //顶部用户信息
+                    SliverToBoxAdapter(
+                      child: _buildRemarkWidget(),
+                    ),
+
+                    //底部工作历史列表
+                    SliverList(
+                        delegate: SliverChildBuilderDelegate(
+                      (context, index) {
+                        return StaffReviewsItem(index: index, item: state.datas[index]);
+                      },
+                      childCount: state.datas.length,
+                    ))
+                  ],
+                ),
+              ).expanded(),
+            ],
+          ),
+        ),
+      );
+    });
+  }
+
+  Widget _buildRemarkWidget() {
+    return Container(
+      padding: EdgeInsets.only(bottom: 22, left: 21, right: 21, top: 18.5),
+      margin: EdgeInsets.only(left: 15, right: 15, top: 14.5, bottom: 5),
+      decoration: BoxDecoration(
+        color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          MyTextView(
+            state.staffName ?? "-",
+            fontSize: 17,
+            textColor: ColorConstants.white,
+            isFontMedium: true,
+            marginBottom: 8,
+          ),
+          Row(
+            children: [
+              RatingWidget(
+                nomalImage: Assets.baseServiceRatingUnselected,
+                selectImage: Assets.baseServiceRatingSelected,
+                size: 21,
+                padding: 5,
+                selectAble: false,
+                integerOnly: false,
+                value: state.reviews ?? 0,
+                onRatingUpdate: (value) {},
+              ),
+              MyTextView(
+                "${state.reviews.toString()} (${state.reviewCount} Reviews)",
+                fontSize: 14,
+                marginLeft: 12,
+                textColor: ColorConstants.textYellowF8AE00,
+                isFontMedium: true,
+              ).expanded(),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 10 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_state.dart

@@ -0,0 +1,10 @@
+import 'package:domain/entity/response/t_h_employee_remarks_entity.dart';
+
+class AppliedErStaffReviewsState {
+  String? memberId;
+  String? staffName;
+  double? reviews;
+  String? reviewCount;
+
+  List<THEmployeeRemarksReviews> datas = [];
+}

+ 151 - 0
packages/cpt_th/lib/modules/job_er/applied_er_staff_reviews/applied_staff_reviews_item.dart

@@ -0,0 +1,151 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:domain/entity/response/t_h_employee_remarks_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_text_view.dart';
+import 'package:widgets/shatter/rating_widget.dart';
+
+/*
+ * 员工的评价记录
+ */
+class StaffReviewsItem extends StatelessWidget {
+  final int index;
+  final THEmployeeRemarksReviews item;
+
+  StaffReviewsItem({
+    required this.index,
+    required this.item,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.only(bottom: 25, left: 21,right: 21,top: 18.5),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          MyTextView(
+            item.employerName ?? "",
+            isFontRegular: true,
+            textColor: Colors.white,
+            fontSize: 17,
+          ),
+
+          //态度评分
+          Row(
+            children: [
+              MyTextView(
+                "Attitude".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 15,
+              ).expanded(flex: 2),
+              RatingWidget(
+                nomalImage: Assets.baseServiceRatingUnselected,
+                selectImage: Assets.baseServiceRatingSelected,
+                size: 21,
+                padding: 5,
+                selectAble: false,
+                integerOnly: true,
+                value: item.attitudeRate,
+                onRatingUpdate: (value) {},
+              ).expanded(flex: 3)
+            ],
+          ).marginOnly(top: 15),
+
+          //表现评分
+          Row(
+            children: [
+              MyTextView(
+                "Performance".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 15,
+              ).expanded(flex: 2),
+              RatingWidget(
+                nomalImage: Assets.baseServiceRatingUnselected,
+                selectImage: Assets.baseServiceRatingSelected,
+                size: 21,
+                padding: 5,
+                selectAble: false,
+                integerOnly: true,
+                value: item.performanceRate,
+                onRatingUpdate: (value) {},
+              ).expanded(flex: 3)
+            ],
+          ).marginOnly(top: 15),
+
+          //经验评分
+          Row(
+            children: [
+              MyTextView(
+                "Experience".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 15,
+              ).expanded(flex: 2),
+              RatingWidget(
+                nomalImage: Assets.baseServiceRatingUnselected,
+                selectImage: Assets.baseServiceRatingSelected,
+                size: 21,
+                padding: 5,
+                selectAble: false,
+                integerOnly: true,
+                value: item.experienceRate,
+                onRatingUpdate: (value) {},
+              ).expanded(flex: 3)
+            ],
+          ).marginOnly(top: 15),
+
+          //着装评分
+          Row(
+            children: [
+              MyTextView(
+                "Grooming".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 15,
+              ).expanded(flex: 2),
+              RatingWidget(
+                nomalImage: Assets.baseServiceRatingUnselected,
+                selectImage: Assets.baseServiceRatingSelected,
+                size: 21,
+                padding: 5,
+                selectAble: false,
+                integerOnly: true,
+                value: item.groomingRate,
+                onRatingUpdate: (value) {},
+              ).expanded(flex: 3)
+            ],
+          ).marginOnly(top: 15),
+
+          MyTextView(
+            item.feedback ?? "",
+            textColor: Colors.white,
+            fontSize: 15,
+            isFontRegular: true,
+            borderColor: Color(0XFF6D92BA),
+            borderWidth: 0.5,
+            boxHeight: 130,
+            boxWidth: double.infinity,
+            paddingTop: 15,
+            paddingLeft: 12.5,
+            paddingRight: 12.5,
+            paddingBottom: 15,
+            marginTop: 18,
+          ),
+
+        ],
+      ),
+    );
+  }
+}

+ 98 - 0
packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_controller.dart

@@ -0,0 +1,98 @@
+import 'package:domain/entity/response/job_list_applied_work_flow_entity.dart';
+import 'package:domain/repository/th_er_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'applied_er_workflow_state.dart';
+
+/*
+ * 已申请的员工状态审核流
+ */
+class  AppliedErWorkflowController extends GetxController with DioCancelableMixin{
+  final THERRepository _erRepository = Get.find();
+  final AppliedErWorkflowState state = AppliedErWorkflowState();
+
+  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: false,
+  );
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    fetchWorkFlowList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _needShowPlaceholder = true;
+    fetchWorkFlowList();
+  }
+
+  /// 获取服务器数据,成员考勤列表
+  Future fetchWorkFlowList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    //获取到数据
+    var result = await _erRepository.fetchAppliedWorkFlow(
+      state.appliedId,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      handleList(result.data?.records);
+      refreshController.finishRefresh(IndicatorResult.success);
+    } else {
+      errorMessage = result.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+      refreshController.finishRefresh(IndicatorResult.fail);
+    }
+
+    //最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<JobListAppliedWorkFlowRecords>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      state.datas.clear();
+      state.datas.addAll(list);
+      //更新状态
+      changeLoadingState(LoadState.State_Success);
+    } else {
+      //展示无数据的布局
+      state.datas.clear();
+      changeLoadingState(LoadState.State_Empty);
+    }
+  }
+
+  @override
+  void onReady() async {
+    super.onReady();
+    fetchWorkFlowList();
+  }
+
+  @override
+  void onClose() {
+    super.onClose();
+    state.datas.clear();
+  }
+}

+ 102 - 0
packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_page.dart

@@ -0,0 +1,102 @@
+
+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/widget_export.dart';
+
+import 'applied_er_workflow_controller.dart';
+import 'applied_er_workflow_state.dart';
+import 'applied_workflow_item.dart';
+
+/*
+ * 已申请的员工-状态工作流列表
+ */
+class AppliedErWorkflowPage extends BaseStatefulPage<AppliedErWorkflowController> {
+  AppliedErWorkflowPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(String? appliedId) {
+    return Get.start(RouterPath.THJobAppliedStaffWorkflow,arguments: {'appliedId': appliedId});
+  }
+
+  @override
+  AppliedErWorkflowController createRawController() {
+    return AppliedErWorkflowController();
+  }
+
+  @override
+  State<AppliedErWorkflowPage> createState() => _AppliedWorkflowState();
+
+}
+
+class _AppliedWorkflowState extends BaseState<AppliedErWorkflowPage, AppliedErWorkflowController> {
+
+  late AppliedErWorkflowState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+    state.appliedId = Get.arguments['appliedId'];
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return  SafeArea(
+        bottom: MediaQuery.of(context).padding.bottom > 38,
+          top: false,
+          child: Container(
+            width: double.infinity,
+            height: double.infinity,
+            padding: EdgeInsets.only(top:ScreenUtil.getStatusBarH(context)),
+            decoration: const BoxDecoration(
+              gradient: LinearGradient(
+                colors: [
+                  Color(0xFF091D44),
+                  Color(0xFF245A8A),
+                  Color(0xFF7F7CEC),
+                ],
+                begin: Alignment.topCenter,
+                end: Alignment.bottomCenter,
+              ),
+            ),
+            child: Column(
+              children: [
+                MyAppBar.titleBar(context, "Workflow".tr),
+
+                EasyRefresh(
+                  controller: controller.refreshController,
+                  onRefresh: controller.onRefresh,
+                  child: LoadStateLayout(
+                    state: controller.loadingState,
+                    errorMessage: controller.errorMessage,
+                    errorRetry: () {
+                      controller.retryRequest();
+                    },
+                    successSliverWidget: [
+                      SliverList(
+                          delegate: SliverChildBuilderDelegate((context, index) {
+                              return AppliedWorkFlowItem(index: index,item: state.datas[index]);
+                            },
+                            childCount: state.datas.length,
+                          ))
+                    ],
+                  ),
+                ).marginOnly(top: 5,bottom: 5).expanded(),
+              ],
+            ).marginOnly(top: 10),
+          ),
+        );
+    });
+  }
+}
+
+

+ 10 - 0
packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_er_workflow_state.dart

@@ -0,0 +1,10 @@
+import 'package:domain/entity/response/job_list_applied_work_flow_entity.dart';
+
+class AppliedErWorkflowState {
+
+  String? appliedId;
+
+  //页面的列表数据
+  List<JobListAppliedWorkFlowRecords> datas = [];
+
+}

+ 228 - 0
packages/cpt_th/lib/modules/job_er/applied_er_workflow/applied_workflow_item.dart

@@ -0,0 +1,228 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/job_list_applied_work_flow_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_text_view.dart';
+
+/**
+ * 用工请求的工作流列表Item
+ */
+class AppliedWorkFlowItem extends StatelessWidget {
+  final int index;
+  final JobListAppliedWorkFlowRecords item;
+
+  AppliedWorkFlowItem({
+    required this.index,
+    required this.item,
+  });
+
+  @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: [
+          //Node
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Node:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              MyTextView(
+                item.nodeName ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ),
+
+          // assigneeType
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Type:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //日期时间
+              MyTextView(
+                item.assigneeTypeShow ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // Designation
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Designation:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //人数
+              MyTextView(
+                item.designationShow ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 状态
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Status:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //状态
+              MyTextView(
+                item.statusShow == null ? "" : item.statusShow!.tr,
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: "Approved" == item.statusShow
+                    ? ColorConstants.textGreen05DC82
+                    : "Rejected" == item.statusShow
+                    ? ColorConstants.textRedFF6262
+                    : "Recall" == item.statusShow
+                    ? ColorConstants.textYellowFFBB1B
+                    : ColorConstants.textBlue06D9FF,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // Operator
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Operator:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //发布状态
+              MyTextView(
+                item.auditName ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 操作时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Audit Time:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.auditTime ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 创建时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Created At:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.createdAt ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // Remark
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "Remark:".tr,
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //时间
+              MyTextView(
+                item.auditMark ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+        ],
+      ),
+    );
+  }
+}

+ 2 - 1
packages/cpt_th/lib/modules/job_er/job_list_er/job_list_er_controller.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_th/modules/job_er/applied_er/applied_er_page.dart';
 import 'package:cpt_th/modules/labour_er/labour_request_er_add/labour_request_er_add_page.dart';
 import 'package:domain/entity/response/job_list_e_r_option_entity.dart';
 import 'package:domain/entity/response/labour_list_e_r_entity.dart';
@@ -208,7 +209,7 @@ class JobListController extends GetxController with DioCancelableMixin {
 
   /// 去已申请的成员列表
   void gotoJobAppliedPage(LabourListERRows data) {
-    ToastEngine.show("去已申请的成员列表");
+    AppliedErPage.startInstance(data.jobId);
   }
 
   /// 删除当前的工作

+ 1 - 1
packages/cpt_th/lib/modules/job_er/job_list_er/job_list_er_state.dart

@@ -8,7 +8,7 @@ class JobListErState {
   final TextEditingController searchController = TextEditingController();
   String keyword = "";
   DateTime? selectedStartDate = DateTime.now();
-  DateTime? selectedEndDate = DateTime.now();
+  DateTime? selectedEndDate;
   String? selectedStatusId;
   String? selectedOutletId;
   String? selectedDivisionId;

+ 35 - 0
packages/cpt_th/lib/router/th_router.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_th/modules/job_er/applied_er_edit/applied_er_edit_page.dart';
 import 'package:get/get.dart';
 import 'package:router/path/router_path.dart';
 
@@ -8,6 +9,10 @@ import '../modules/job/attendance_review_list/attendance_review_page.dart';
 import '../modules/job/job_applied/job_applied_page.dart';
 import '../modules/job/job_applied_edit/job_applied_edit_page.dart';
 import '../modules/job/job_list/job_list_page.dart';
+import '../modules/job_er/applied_er/applied_er_page.dart';
+import '../modules/job_er/applied_er_staff_detail/applied_er_staff_detail_page.dart';
+import '../modules/job_er/applied_er_staff_reviews/applied_er_staff_reviews_page.dart';
+import '../modules/job_er/applied_er_workflow/applied_er_workflow_page.dart';
 import '../modules/job_er/job_list_er/job_list_er_page.dart';
 import '../modules/labour_er/labour_request_er/labour_request_list_page.dart';
 import '../modules/labour_er/labour_request_er_add/labour_request_er_add_page.dart';
@@ -154,6 +159,36 @@ class THPageRouter {
       page: () => JobListERPage(),
     ),
 
+    //ER 已申请列表
+    GetPage(
+      name: RouterPath.THJobAppliedER,
+      page: () => AppliedErPage(),
+    ),
+
+    //ER 已申请列表,修改员工信息
+    GetPage(
+      name: RouterPath.THJobAppliedEditER,
+      page: () => AppliedErEditPage(),
+    ),
+
+    //ER 已申请列表,员工详情页面
+    GetPage(
+      name: RouterPath.THJobAppliedEmployeeER,
+      page: () => AppliedErStaffDetailPage(),
+    ),
+
+    //ER 已申请列表,员工详情评价页面
+    GetPage(
+      name: RouterPath.THJobAppliedEmployeeRemarkER,
+      page: () => AppliedErStaffReviewsPage(),
+    ),
+
+    //ER 已申请列表,员工详情评价页面
+    GetPage(
+      name: RouterPath.THJobAppliedStaffWorkflow,
+      page: () => AppliedErWorkflowPage(),
+    ),
+
 
   ];
 }

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

@@ -549,4 +549,47 @@ class ApiConstants {
 
   // ER 的用工请求编辑提交
   static const apiERLabourRequestEditSubmitTH = "/index.php/api/er/job/edit-submit";
+
+  //ER 工作 Applied Index
+  static const apiERAppliedOptionTH = "/index.php/api/er/applied/index";
+
+  //ER 工作 Applied List
+  static const apiERAppliedListTH = "/index.php/api/er/applied/table";
+
+  //ER 工作 Applied 批量批准
+  static const apiERAppliedApproveTH = "/index.php/api/er/applied/batch-approve";
+
+  //ER 工作 Applied 批量修改
+  static const apiERAppliedEditTH = "/index.php/api/er/applied/batch-modify";
+
+  //ER 工作 Applied 编辑个人考勤
+  static const apiERAppliedEditAttTH = "/index.php/api/er/applied/view-edit";
+
+  //ER 工作 Applied 编辑个人考勤的提交
+  static const apiERAppliedEditAttSubmitTH = "/index.php/api/er/applied/edit-submit";
+
+  //ER 工作 Applied 添加员工列表
+  static const apiERAppliedAddEmployeeTH = "/index.php/api/er/applied/staff-table";
+
+  //ER 工作 Applied 添加员工提交
+  static const apiERAppliedAddEmployeeSubmitTH = "/index.php/api/er/applied/staff-submit";
+
+  //ER 员工信息
+  static const apiEREmployeeInfoTH = "/index.php/api/er/member/detail";
+
+  //ER 员工工作历史
+  static const apiEREmployeeHistoryTH = "/index.php/api/er/member/history";
+
+  //ER 员工评价列表
+  static const apiEREmployeeEvaluationTH = "/index.php/api/er/member/remarks";
+
+  // 工作已申请员工列表-评价员工的详情数据
+  static const apiERAppliedStaffReviewIndexTH = "/index.php/api/er/applied/view-remark";
+
+  // 工作已申请员工列表-评价员工的提交
+  static const apiERAppliedStaffReviewSubmitTH = "/index.php/api/er/applied/remark-submit";
+
+  // 工作已申请员工列表-评价员工的提交
+  static const apiERAppliedStaffStateWorkflowTH = "/index.php/api/er/applied/view-status";
+
 }

+ 1 - 1
packages/cs_domain/lib/entity/response/job_list_applied_work_flow_entity.dart

@@ -34,7 +34,7 @@ class JobListAppliedWorkFlowRecords {
 	@JSONField(name: "audit_time")
 	String? auditTime = null;
 	@JSONField(name: "audit_mark")
-	dynamic auditMark;
+	String? auditMark;
 	@JSONField(name: "created_at")
 	String? createdAt = null;
 	@JSONField(name: "assignee_type_show")

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

@@ -9,6 +9,8 @@ class JobListRemarkViewEntity {
   int appliedId = 0;
   @JSONField(name: "member_name")
   String? memberName = null;
+  @JSONField(name: "labourer_name")
+  String? labourerName = null;
   @JSONField(name: "attitude_rate")
   double attitudeRate = 5.0;
   @JSONField(name: "grooming_rate")
@@ -18,6 +20,7 @@ class JobListRemarkViewEntity {
   @JSONField(name: "experience_rate")
   double experienceRate = 5.0;
   String? content = null;
+  String? feedback = null;
   String? disabled = null;
 
   JobListRemarkViewEntity();

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

@@ -47,6 +47,8 @@ class StaffLabourHistoryRows {
 	int status = 0;
 	@JSONField(name: "status_show")
 	String? statusShow = null;
+	@JSONField(name: "employer_name")
+	String? employerName = null;
 	@JSONField(name: "applied_at")
 	String? appliedAt = null;
 	@JSONField(name: "security_in")

+ 190 - 0
packages/cs_domain/lib/entity/response/t_h_applied_edit_entity.dart

@@ -0,0 +1,190 @@
+import 'package:domain/entity/response/index_option_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_applied_edit_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_applied_edit_entity.g.dart';
+
+@JsonSerializable()
+class THAppliedEditEntity {
+	THAppliedEditApplied? applied;
+	@JSONField(name: "applied_id")
+	String? appliedId;
+	@JSONField(name: "member_id")
+	String? memberId;
+	String? remark;
+	@JSONField(name: "start_time")
+	String? startTime;
+	@JSONField(name: "end_time")
+	String? endTime;
+	@JSONField(name: "default_start")
+	String? defaultStart;
+	@JSONField(name: "default_end")
+	String? defaultEnd;
+	@JSONField(name: "security_in")
+	String? securityIn;
+	@JSONField(name: "def_security_in")
+	String? defSecurityIn;
+	@JSONField(name: "security_out")
+	String? securityOut;
+	@JSONField(name: "def_security_out")
+	String? defSecurityOut;
+	@JSONField(name: "work_in")
+	String? workIn;
+	@JSONField(name: "def_work_in")
+	String? defWorkIn;
+	@JSONField(name: "work_out")
+	String? workOut;
+	@JSONField(name: "def_work_out")
+	String? defWorkOut;
+	@JSONField(name: "adjust_hours")
+	String? adjustHours;
+	@JSONField(name: "subtract_hours")
+	String? subtractHours;
+	@JSONField(name: "ballroom_list")
+	List<String> ballroomList = [];
+	@JSONField(name: "status_list")
+	List<IndexOptionEntity> statusList = [];
+	@JSONField(name: "reason_list")
+	List<IndexOptionEntity> reasonList = [];
+
+	THAppliedEditEntity();
+
+	factory THAppliedEditEntity.fromJson(Map<String, dynamic> json) => $THAppliedEditEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedEditEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THAppliedEditApplied {
+	String? id;
+	@JSONField(name: "job_id")
+	String? jobId;
+	@JSONField(name: "s_id")
+	String? sId;
+	@JSONField(name: "member_id")
+	String? memberId;
+	@JSONField(name: "labourer_id")
+	String? labourerId;
+	@JSONField(name: "labourer_name")
+	String? labourerName;
+	@JSONField(name: "labourer_nric")
+	String? labourerNric;
+	@JSONField(name: "source_type")
+	int sourceType = 0;
+	@JSONField(name: "employer_id")
+	String? employerId;
+	@JSONField(name: "employer_name")
+	String? employerName;
+	@JSONField(name: "agency_id")
+	String? agencyId;
+	@JSONField(name: "agency_name")
+	String? agencyName;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "outlet_id")
+	String? outletId;
+	@JSONField(name: "outlet_name")
+	String? outletName;
+	@JSONField(name: "ballroom_id")
+	String? ballroomId;
+	@JSONField(name: "ballroom_name")
+	String? ballroomName;
+	@JSONField(name: "job_date")
+	String? jobDate;
+	@JSONField(name: "start_time")
+	int? startTime;
+	@JSONField(name: "end_time")
+	int? endTime;
+	@JSONField(name: "working_hours")
+	String? workingHours;
+	@JSONField(name: "adjust_hours")
+	String? adjustHours;
+	@JSONField(name: "total_hours")
+	String? totalHours;
+	@JSONField(name: "hourly_rate")
+	String? hourlyRate;
+	@JSONField(name: "gross_wage")
+	String? grossWage;
+	@JSONField(name: "security_clock_in")
+	int? securityClockIn;
+	@JSONField(name: "security_clock_out")
+	int? securityClockOut;
+	@JSONField(name: "work_clock_in")
+	int? workClockIn;
+	@JSONField(name: "work_clock_out")
+	int? workClockOut;
+	@JSONField(name: "security_in")
+	int? securityIn;
+	@JSONField(name: "security_out")
+	int? securityOut;
+	@JSONField(name: "work_in")
+	int? workIn;
+	@JSONField(name: "work_out")
+	int? workOut;
+	String? status ;
+	@JSONField(name: "remark_status")
+	int? remarkStatus;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	@JSONField(name: "updated_at")
+	String? updatedAt;
+	@JSONField(name: "sync_payroll")
+	int? syncPayroll;
+	@JSONField(name: "sign_image")
+	String? signImage;
+	@JSONField(name: "event_name")
+	String? eventName;
+	@JSONField(name: "event_type")
+	String? eventType;
+	@JSONField(name: "working_type")
+	int? workingType;
+	@JSONField(name: "epf_employer")
+	String? epfEmployer;
+	@JSONField(name: "epf_employee")
+	String? epfEmployee;
+	@JSONField(name: "epf_total")
+	String? epfTotal;
+	@JSONField(name: "net_pay")
+	String? netPay;
+	String? socso;
+	@JSONField(name: "payment_status")
+	int? paymentStatus;
+	@JSONField(name: "paid_time")
+	String? paidTime;
+	@JSONField(name: "agency_rate")
+	String? agencyRate;
+	@JSONField(name: "agency_wage")
+	String? agencyWage;
+	String? remark;
+	@JSONField(name: "reason_type")
+	String? reasonType;
+	@JSONField(name: "audit_reject")
+	int? auditReject;
+	@JSONField(name: "revise_hours")
+	String? reviseHours;
+	@JSONField(name: "revise_gross_wage")
+	String? reviseGrossWage;
+	@JSONField(name: "revise_agency_wage")
+	String? reviseAgencyWage;
+	@JSONField(name: "is_ot")
+	int? isOt;
+	@JSONField(name: "reject_msg")
+	String? rejectMsg;
+
+	THAppliedEditApplied();
+
+	factory THAppliedEditApplied.fromJson(Map<String, dynamic> json) => $THAppliedEditAppliedFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedEditAppliedToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+

+ 48 - 0
packages/cs_domain/lib/entity/response/t_h_applied_employee_entity.dart

@@ -0,0 +1,48 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_applied_employee_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_applied_employee_entity.g.dart';
+
+@JsonSerializable()
+class THAppliedEmployeeEntity {
+	int total = 0;
+	List<THAppliedEmployeeRows> rows = [];
+
+	THAppliedEmployeeEntity();
+
+	factory THAppliedEmployeeEntity.fromJson(Map<String, dynamic> json) => $THAppliedEmployeeEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedEmployeeEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THAppliedEmployeeRows {
+	String? id;
+	String? name;
+	String? gender;
+	String? mobile;
+	String? nric;
+	@JSONField(name: "profile_picture")
+	String? profilePicture;
+	int status = 0;
+	@JSONField(name: "apply_state")
+	int applyState = 0;
+
+	bool isSelected = false;  //自定义属性
+
+	THAppliedEmployeeRows();
+
+	factory THAppliedEmployeeRows.fromJson(Map<String, dynamic> json) => $THAppliedEmployeeRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedEmployeeRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 117 - 0
packages/cs_domain/lib/entity/response/t_h_applied_index_entity.dart

@@ -0,0 +1,117 @@
+import 'package:domain/entity/response/index_option_entity.dart';
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_applied_index_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_applied_index_entity.g.dart';
+
+@JsonSerializable()
+class THAppliedIndexEntity {
+	@JSONField(name: "job_id")
+	String? jobId;
+	THAppliedIndexJob? job;
+	@JSONField(name: "status_list")
+	List<IndexOptionEntity> statusList = [];
+	@JSONField(name: "can_append")
+	bool? canAppend;
+	@JSONField(name: "source_show")
+	String? sourceShow;
+	@JSONField(name: "job_date")
+	String? jobDate;
+	@JSONField(name: "is_super")
+	bool? isSuper;
+
+	THAppliedIndexEntity();
+
+	factory THAppliedIndexEntity.fromJson(Map<String, dynamic> json) => $THAppliedIndexEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedIndexEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THAppliedIndexJob {
+	String? id;
+	@JSONField(name: "employer_id")
+	String? employerId;
+	@JSONField(name: "employer_name")
+	String? employerName;
+	@JSONField(name: "e_admin_id")
+	String? eAdminId;
+	@JSONField(name: "yy_job_id")
+	String? yyJobId;
+	@JSONField(name: "source_type")
+	String? sourceType;
+	@JSONField(name: "agency_id")
+	String? agencyId;
+	@JSONField(name: "agency_name")
+	String? agencyName;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "outlet_id")
+	String? outletId;
+	@JSONField(name: "outlet_name")
+	String? outletName;
+	@JSONField(name: "job_date")
+	String? jobDate;
+	@JSONField(name: "start_time")
+	int? startTime;
+	@JSONField(name: "end_time")
+	int? endTime;
+	@JSONField(name: "working_hours")
+	String? workingHours;
+	@JSONField(name: "hourly_rate")
+	String? hourlyRate;
+	@JSONField(name: "hiring_num")
+	String? hiringNum;
+	@JSONField(name: "real_num")
+	String? realNum;
+	int status = 0;
+	String? description;
+	@JSONField(name: "confirm_status")
+	int confirmStatus = 0;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	@JSONField(name: "updated_at")
+	String? updatedAt;
+	@JSONField(name: "deleted_at")
+	String? deletedAt;
+	@JSONField(name: "event_name")
+	String? eventName;
+	@JSONField(name: "event_type")
+	String? eventType;
+	@JSONField(name: "with_typhoid")
+	String? withTyphoid;
+	@JSONField(name: "sync_payroll")
+	String? syncPayroll;
+	@JSONField(name: "agency_rate")
+	String? agencyRate;
+	@JSONField(name: "request_id")
+	String? requestId;
+	@JSONField(name: "job_title_id")
+	String? jobTitleId;
+	@JSONField(name: "is_ot")
+	int isOt = 0;
+	@JSONField(name: "position_id")
+	String? positionId;
+	@JSONField(name: "sex_limit")
+	int sexLimit = 0;
+	@JSONField(name: "male_limit")
+	String? maleLimit;
+	@JSONField(name: "female_limit")
+	String? femaleLimit;
+
+	THAppliedIndexJob();
+
+	factory THAppliedIndexJob.fromJson(Map<String, dynamic> json) => $THAppliedIndexJobFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedIndexJobToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 114 - 0
packages/cs_domain/lib/entity/response/t_h_applied_table_entity.dart

@@ -0,0 +1,114 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_applied_table_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_applied_table_entity.g.dart';
+
+@JsonSerializable()
+class THAppliedTableEntity {
+	int total = 0;
+	List<THAppliedTableRows> rows = [];
+
+	THAppliedTableEntity();
+
+	factory THAppliedTableEntity.fromJson(Map<String, dynamic> json) => $THAppliedTableEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedTableEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THAppliedTableRows {
+	String? id;
+	@JSONField(name: "member_id")
+	String? memberId;
+	@JSONField(name: "s_id")
+	String? sId;
+	@JSONField(name: "job_title")
+	String? jobTitle;
+	@JSONField(name: "outlet_name")
+	String? outletName;
+	@JSONField(name: "ballroom_name")
+	String? ballroomName;
+	@JSONField(name: "labourer_name")
+	String? labourerName;
+	@JSONField(name: "labourer_nric")
+	String? labourerNric;
+	@JSONField(name: "job_date")
+	String? jobDate;
+	@JSONField(name: "start_time")
+	String? startTime;
+	@JSONField(name: "end_time")
+	String? endTime;
+	@JSONField(name: "adjust_hours")
+	String? adjustHours;
+	@JSONField(name: "working_hours")
+	String? workingHours;
+	@JSONField(name: "total_hours")
+	String? totalHours;
+	int status = 0;
+	@JSONField(name: "status_show")
+	String? statusShow;
+	@JSONField(name: "hourly_rate")
+	String? hourlyRate;
+	@JSONField(name: "remark_status")
+	String? remarkStatus;
+	@JSONField(name: "security_in")
+	THAppliedTableCheckInOut? securityIn;
+	@JSONField(name: "security_out")
+	THAppliedTableCheckInOut? securityOut;
+	@JSONField(name: "work_in")
+	THAppliedTableCheckInOut? workIn;
+	@JSONField(name: "work_out")
+	THAppliedTableCheckInOut? workOut;
+	@JSONField(name: "s_in")
+	String? sIn;
+	@JSONField(name: "s_out")
+	String? sOut;
+	@JSONField(name: "w_in")
+	String? wIn;
+	@JSONField(name: "w_out")
+	String? wOut;
+	@JSONField(name: "audit_reject")
+	String? auditReject;
+	@JSONField(name: "revise_hours")
+	String? reviseHours;
+	@JSONField(name: "clothing_size")
+	String? clothingSize;
+
+	bool isSelected = false;  //自定义属性,是否选中
+
+	THAppliedTableRows();
+
+	factory THAppliedTableRows.fromJson(Map<String, dynamic> json) => $THAppliedTableRowsFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedTableRowsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THAppliedTableCheckInOut {
+	String? time;
+	String? temp;
+	String? image;
+	int? changed;
+
+	THAppliedTableCheckInOut();
+
+	factory THAppliedTableCheckInOut.fromJson(Map<String, dynamic> json) => $THAppliedTableCheckInOutFromJson(json);
+
+	Map<String, dynamic> toJson() => $THAppliedTableCheckInOutToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+

+ 101 - 0
packages/cs_domain/lib/entity/response/t_h_employee_detail_entity.dart

@@ -0,0 +1,101 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_employee_detail_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_employee_detail_entity.g.dart';
+
+@JsonSerializable()
+class THEmployeeDetailEntity {
+	@JSONField(name: "member_id")
+	String? memberId;
+	@JSONField(name: "staff_id")
+	String? staffId;
+	THEmployeeDetailStaff? staff;
+	@JSONField(name: "worker_name")
+	String? workerName;
+	String? mobile;
+	String? icon;
+	String? sex;
+	String? nric;
+	@JSONField(name: "hourly_rate")
+	String? hourlyRate;
+	@JSONField(name: "clothing_size")
+	String? clothingSize;
+	THEmployeeDetailReviews? reviews;
+
+	THEmployeeDetailEntity();
+
+	factory THEmployeeDetailEntity.fromJson(Map<String, dynamic> json) => $THEmployeeDetailEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THEmployeeDetailEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THEmployeeDetailStaff {
+	String? id;
+	String? name;
+	String? sex;
+	String? mobile;
+	String? nric;
+	@JSONField(name: "profile_picture")
+	String? profilePicture;
+	@JSONField(name: "visitor_key")
+	String? visitorKey;
+	@JSONField(name: "yy_member_id")
+	String? yyMemberId;
+	@JSONField(name: "created_at")
+	String? createdAt;
+	@JSONField(name: "updated_at")
+	String? updatedAt;
+	String? password;
+	@JSONField(name: "default_staff")
+	String? defaultStaff;
+	@JSONField(name: "typhoid_date")
+	String? typhoidDate;
+	@JSONField(name: "typhoid_file")
+	String? typhoidFile;
+	@JSONField(name: "food_hygiene")
+	String? foodHygiene;
+	@JSONField(name: "criminal_file")
+	String? criminalFile;
+	@JSONField(name: "criminal_date")
+	String? criminalDate;
+	String? email;
+	@JSONField(name: "own_staff_id")
+	String? ownStaffId;
+	@JSONField(name: "clothing_size")
+	String? clothingSize;
+
+	THEmployeeDetailStaff();
+
+	factory THEmployeeDetailStaff.fromJson(Map<String, dynamic> json) => $THEmployeeDetailStaffFromJson(json);
+
+	Map<String, dynamic> toJson() => $THEmployeeDetailStaffToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THEmployeeDetailReviews {
+	String? count;
+	@JSONField(name: "avg_score")
+	String? avgScore;
+
+	THEmployeeDetailReviews();
+
+	factory THEmployeeDetailReviews.fromJson(Map<String, dynamic> json) => $THEmployeeDetailReviewsFromJson(json);
+
+	Map<String, dynamic> toJson() => $THEmployeeDetailReviewsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

+ 55 - 0
packages/cs_domain/lib/entity/response/t_h_employee_remarks_entity.dart

@@ -0,0 +1,55 @@
+import 'package:domain/generated/json/base/json_field.dart';
+import 'package:domain/generated/json/t_h_employee_remarks_entity.g.dart';
+import 'dart:convert';
+export 'package:domain/generated/json/t_h_employee_remarks_entity.g.dart';
+
+@JsonSerializable()
+class THEmployeeRemarksEntity {
+	int count = 0;
+	@JSONField(name: "avg_score")
+	String? avgScore;
+	List<THEmployeeRemarksReviews> reviews = [];
+	@JSONField(name: "member_id")
+	int? memberId;
+	@JSONField(name: "labourer_name")
+	String? labourerName;
+
+	THEmployeeRemarksEntity();
+
+	factory THEmployeeRemarksEntity.fromJson(Map<String, dynamic> json) => $THEmployeeRemarksEntityFromJson(json);
+
+	Map<String, dynamic> toJson() => $THEmployeeRemarksEntityToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}
+
+@JsonSerializable()
+class THEmployeeRemarksReviews {
+	@JSONField(name: "employer_name")
+	String? employerName;
+	@JSONField(name: "attitude_rate")
+	double attitudeRate = 0;
+	@JSONField(name: "grooming_rate")
+	double groomingRate = 0;
+	@JSONField(name: "performance_rate")
+	double performanceRate = 0;
+	@JSONField(name: "experience_rate")
+	double experienceRate = 0;
+	String? feedback;
+	@JSONField(name: "created_at")
+	String? createdAt;
+
+	THEmployeeRemarksReviews();
+
+	factory THEmployeeRemarksReviews.fromJson(Map<String, dynamic> json) => $THEmployeeRemarksReviewsFromJson(json);
+
+	Map<String, dynamic> toJson() => $THEmployeeRemarksReviewsToJson(this);
+
+	@override
+	String toString() {
+		return jsonEncode(this);
+	}
+}

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

@@ -85,6 +85,12 @@ import 'package:domain/entity/response/staff_report_v_n_entity.dart';
 import 'package:domain/entity/response/staff_request_report_entity.dart';
 import 'package:domain/entity/response/staff_review_history_s_g_entity.dart';
 import 'package:domain/entity/response/switch_project_entity.dart';
+import 'package:domain/entity/response/t_h_applied_edit_entity.dart';
+import 'package:domain/entity/response/t_h_applied_employee_entity.dart';
+import 'package:domain/entity/response/t_h_applied_index_entity.dart';
+import 'package:domain/entity/response/t_h_applied_table_entity.dart';
+import 'package:domain/entity/response/t_h_employee_detail_entity.dart';
+import 'package:domain/entity/response/t_h_employee_remarks_entity.dart';
 import 'package:domain/entity/response/u_k_attendance_entity.dart';
 import 'package:domain/entity/response/u_k_report_attendance_entity.dart';
 import 'package:domain/entity/response/u_k_report_labour_entity.dart';
@@ -733,6 +739,48 @@ class JsonConvert {
     if (<SwitchProjectUserList>[] is M) {
       return data.map<SwitchProjectUserList>((Map<String, dynamic> e) => SwitchProjectUserList.fromJson(e)).toList() as M;
     }
+    if (<THAppliedEditEntity>[] is M) {
+      return data.map<THAppliedEditEntity>((Map<String, dynamic> e) => THAppliedEditEntity.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedEditApplied>[] is M) {
+      return data.map<THAppliedEditApplied>((Map<String, dynamic> e) => THAppliedEditApplied.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedEmployeeEntity>[] is M) {
+      return data.map<THAppliedEmployeeEntity>((Map<String, dynamic> e) => THAppliedEmployeeEntity.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedEmployeeRows>[] is M) {
+      return data.map<THAppliedEmployeeRows>((Map<String, dynamic> e) => THAppliedEmployeeRows.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedIndexEntity>[] is M) {
+      return data.map<THAppliedIndexEntity>((Map<String, dynamic> e) => THAppliedIndexEntity.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedIndexJob>[] is M) {
+      return data.map<THAppliedIndexJob>((Map<String, dynamic> e) => THAppliedIndexJob.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedTableEntity>[] is M) {
+      return data.map<THAppliedTableEntity>((Map<String, dynamic> e) => THAppliedTableEntity.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedTableRows>[] is M) {
+      return data.map<THAppliedTableRows>((Map<String, dynamic> e) => THAppliedTableRows.fromJson(e)).toList() as M;
+    }
+    if (<THAppliedTableCheckInOut>[] is M) {
+      return data.map<THAppliedTableCheckInOut>((Map<String, dynamic> e) => THAppliedTableCheckInOut.fromJson(e)).toList() as M;
+    }
+    if (<THEmployeeDetailEntity>[] is M) {
+      return data.map<THEmployeeDetailEntity>((Map<String, dynamic> e) => THEmployeeDetailEntity.fromJson(e)).toList() as M;
+    }
+    if (<THEmployeeDetailStaff>[] is M) {
+      return data.map<THEmployeeDetailStaff>((Map<String, dynamic> e) => THEmployeeDetailStaff.fromJson(e)).toList() as M;
+    }
+    if (<THEmployeeDetailReviews>[] is M) {
+      return data.map<THEmployeeDetailReviews>((Map<String, dynamic> e) => THEmployeeDetailReviews.fromJson(e)).toList() as M;
+    }
+    if (<THEmployeeRemarksEntity>[] is M) {
+      return data.map<THEmployeeRemarksEntity>((Map<String, dynamic> e) => THEmployeeRemarksEntity.fromJson(e)).toList() as M;
+    }
+    if (<THEmployeeRemarksReviews>[] is M) {
+      return data.map<THEmployeeRemarksReviews>((Map<String, dynamic> e) => THEmployeeRemarksReviews.fromJson(e)).toList() as M;
+    }
     if (<UKAttendanceEntity>[] is M) {
       return data.map<UKAttendanceEntity>((Map<String, dynamic> e) => UKAttendanceEntity.fromJson(e)).toList() as M;
     }
@@ -979,6 +1027,20 @@ class JsonConvertClassCollection {
     (StaffReviewHistorySGReviews).toString(): StaffReviewHistorySGReviews.fromJson,
     (SwitchProjectEntity).toString(): SwitchProjectEntity.fromJson,
     (SwitchProjectUserList).toString(): SwitchProjectUserList.fromJson,
+    (THAppliedEditEntity).toString(): THAppliedEditEntity.fromJson,
+    (THAppliedEditApplied).toString(): THAppliedEditApplied.fromJson,
+    (THAppliedEmployeeEntity).toString(): THAppliedEmployeeEntity.fromJson,
+    (THAppliedEmployeeRows).toString(): THAppliedEmployeeRows.fromJson,
+    (THAppliedIndexEntity).toString(): THAppliedIndexEntity.fromJson,
+    (THAppliedIndexJob).toString(): THAppliedIndexJob.fromJson,
+    (THAppliedTableEntity).toString(): THAppliedTableEntity.fromJson,
+    (THAppliedTableRows).toString(): THAppliedTableRows.fromJson,
+    (THAppliedTableCheckInOut).toString(): THAppliedTableCheckInOut.fromJson,
+    (THEmployeeDetailEntity).toString(): THEmployeeDetailEntity.fromJson,
+    (THEmployeeDetailStaff).toString(): THEmployeeDetailStaff.fromJson,
+    (THEmployeeDetailReviews).toString(): THEmployeeDetailReviews.fromJson,
+    (THEmployeeRemarksEntity).toString(): THEmployeeRemarksEntity.fromJson,
+    (THEmployeeRemarksReviews).toString(): THEmployeeRemarksReviews.fromJson,
     (UKAttendanceEntity).toString(): UKAttendanceEntity.fromJson,
     (UKAttendanceRows).toString(): UKAttendanceRows.fromJson,
     (UKAttendanceInOut).toString(): UKAttendanceInOut.fromJson,

+ 2 - 2
packages/cs_domain/lib/generated/json/job_list_applied_work_flow_entity.g.dart

@@ -55,7 +55,7 @@ JobListAppliedWorkFlowRecords $JobListAppliedWorkFlowRecordsFromJson(Map<String,
   if (auditTime != null) {
     jobListAppliedWorkFlowRecords.auditTime = auditTime;
   }
-  final dynamic auditMark = json['audit_mark'];
+  final String? auditMark = jsonConvert.convert<String>(json['audit_mark']);
   if (auditMark != null) {
     jobListAppliedWorkFlowRecords.auditMark = auditMark;
   }
@@ -95,7 +95,7 @@ extension JobListAppliedWorkFlowRecordsExtension on JobListAppliedWorkFlowRecord
     String? statusShow,
     String? auditName,
     String? auditTime,
-    dynamic auditMark,
+    String? auditMark,
     String? createdAt,
     String? assigneeTypeShow,
     String? designationShow,

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

@@ -11,6 +11,10 @@ JobListRemarkViewEntity $JobListRemarkViewEntityFromJson(Map<String, dynamic> js
   if (memberName != null) {
     jobListRemarkViewEntity.memberName = memberName;
   }
+  final String? labourerName = jsonConvert.convert<String>(json['labourer_name']);
+  if (labourerName != null) {
+    jobListRemarkViewEntity.labourerName = labourerName;
+  }
   final double? attitudeRate = jsonConvert.convert<double>(json['attitude_rate']);
   if (attitudeRate != null) {
     jobListRemarkViewEntity.attitudeRate = attitudeRate;
@@ -31,6 +35,10 @@ JobListRemarkViewEntity $JobListRemarkViewEntityFromJson(Map<String, dynamic> js
   if (content != null) {
     jobListRemarkViewEntity.content = content;
   }
+  final String? feedback = jsonConvert.convert<String>(json['feedback']);
+  if (feedback != null) {
+    jobListRemarkViewEntity.feedback = feedback;
+  }
   final String? disabled = jsonConvert.convert<String>(json['disabled']);
   if (disabled != null) {
     jobListRemarkViewEntity.disabled = disabled;
@@ -42,11 +50,13 @@ Map<String, dynamic> $JobListRemarkViewEntityToJson(JobListRemarkViewEntity enti
   final Map<String, dynamic> data = <String, dynamic>{};
   data['applied_id'] = entity.appliedId;
   data['member_name'] = entity.memberName;
+  data['labourer_name'] = entity.labourerName;
   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['feedback'] = entity.feedback;
   data['disabled'] = entity.disabled;
   return data;
 }
@@ -55,21 +65,25 @@ extension JobListRemarkViewEntityExtension on JobListRemarkViewEntity {
   JobListRemarkViewEntity copyWith({
     int? appliedId,
     String? memberName,
+    String? labourerName,
     double? attitudeRate,
     double? groomingRate,
     double? performanceRate,
     double? experienceRate,
     String? content,
+    String? feedback,
     String? disabled,
   }) {
     return JobListRemarkViewEntity()
       ..appliedId = appliedId ?? this.appliedId
       ..memberName = memberName ?? this.memberName
+      ..labourerName = labourerName ?? this.labourerName
       ..attitudeRate = attitudeRate ?? this.attitudeRate
       ..groomingRate = groomingRate ?? this.groomingRate
       ..performanceRate = performanceRate ?? this.performanceRate
       ..experienceRate = experienceRate ?? this.experienceRate
       ..content = content ?? this.content
+      ..feedback = feedback ?? this.feedback
       ..disabled = disabled ?? this.disabled;
   }
 }

+ 7 - 0
packages/cs_domain/lib/generated/json/staff_labour_history_entity.g.dart

@@ -87,6 +87,10 @@ StaffLabourHistoryRows $StaffLabourHistoryRowsFromJson(Map<String, dynamic> json
   if (statusShow != null) {
     staffLabourHistoryRows.statusShow = statusShow;
   }
+  final String? employerName = jsonConvert.convert<String>(json['employer_name']);
+  if (employerName != null) {
+    staffLabourHistoryRows.employerName = employerName;
+  }
   final String? appliedAt = jsonConvert.convert<String>(json['applied_at']);
   if (appliedAt != null) {
     staffLabourHistoryRows.appliedAt = appliedAt;
@@ -146,6 +150,7 @@ Map<String, dynamic> $StaffLabourHistoryRowsToJson(StaffLabourHistoryRows entity
   data['total_rooms'] = entity.totalRooms;
   data['status'] = entity.status;
   data['status_show'] = entity.statusShow;
+  data['employer_name'] = entity.employerName;
   data['applied_at'] = entity.appliedAt;
   data['security_in'] = entity.securityIn?.toJson();
   data['security_out'] = entity.securityOut?.toJson();
@@ -174,6 +179,7 @@ extension StaffLabourHistoryRowsExtension on StaffLabourHistoryRows {
     int? totalRooms,
     int? status,
     String? statusShow,
+    String? employerName,
     String? appliedAt,
     StaffLabourHistoryRowsSecurityIn? securityIn,
     StaffLabourHistoryRowsSecurityOut? securityOut,
@@ -199,6 +205,7 @@ extension StaffLabourHistoryRowsExtension on StaffLabourHistoryRows {
       ..totalRooms = totalRooms ?? this.totalRooms
       ..status = status ?? this.status
       ..statusShow = statusShow ?? this.statusShow
+      ..employerName = employerName ?? this.employerName
       ..appliedAt = appliedAt ?? this.appliedAt
       ..securityIn = securityIn ?? this.securityIn
       ..securityOut = securityOut ?? this.securityOut

+ 601 - 0
packages/cs_domain/lib/generated/json/t_h_applied_edit_entity.g.dart

@@ -0,0 +1,601 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_applied_edit_entity.dart';
+import 'package:domain/entity/response/index_option_entity.dart';
+
+
+THAppliedEditEntity $THAppliedEditEntityFromJson(Map<String, dynamic> json) {
+  final THAppliedEditEntity tHAppliedEditEntity = THAppliedEditEntity();
+  final THAppliedEditApplied? applied = jsonConvert.convert<THAppliedEditApplied>(json['applied']);
+  if (applied != null) {
+    tHAppliedEditEntity.applied = applied;
+  }
+  final String? appliedId = jsonConvert.convert<String>(json['applied_id']);
+  if (appliedId != null) {
+    tHAppliedEditEntity.appliedId = appliedId;
+  }
+  final String? memberId = jsonConvert.convert<String>(json['member_id']);
+  if (memberId != null) {
+    tHAppliedEditEntity.memberId = memberId;
+  }
+  final String? remark = jsonConvert.convert<String>(json['remark']);
+  if (remark != null) {
+    tHAppliedEditEntity.remark = remark;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    tHAppliedEditEntity.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    tHAppliedEditEntity.endTime = endTime;
+  }
+  final String? defaultStart = jsonConvert.convert<String>(json['default_start']);
+  if (defaultStart != null) {
+    tHAppliedEditEntity.defaultStart = defaultStart;
+  }
+  final String? defaultEnd = jsonConvert.convert<String>(json['default_end']);
+  if (defaultEnd != null) {
+    tHAppliedEditEntity.defaultEnd = defaultEnd;
+  }
+  final String? securityIn = jsonConvert.convert<String>(json['security_in']);
+  if (securityIn != null) {
+    tHAppliedEditEntity.securityIn = securityIn;
+  }
+  final String? defSecurityIn = jsonConvert.convert<String>(json['def_security_in']);
+  if (defSecurityIn != null) {
+    tHAppliedEditEntity.defSecurityIn = defSecurityIn;
+  }
+  final String? securityOut = jsonConvert.convert<String>(json['security_out']);
+  if (securityOut != null) {
+    tHAppliedEditEntity.securityOut = securityOut;
+  }
+  final String? defSecurityOut = jsonConvert.convert<String>(json['def_security_out']);
+  if (defSecurityOut != null) {
+    tHAppliedEditEntity.defSecurityOut = defSecurityOut;
+  }
+  final String? workIn = jsonConvert.convert<String>(json['work_in']);
+  if (workIn != null) {
+    tHAppliedEditEntity.workIn = workIn;
+  }
+  final String? defWorkIn = jsonConvert.convert<String>(json['def_work_in']);
+  if (defWorkIn != null) {
+    tHAppliedEditEntity.defWorkIn = defWorkIn;
+  }
+  final String? workOut = jsonConvert.convert<String>(json['work_out']);
+  if (workOut != null) {
+    tHAppliedEditEntity.workOut = workOut;
+  }
+  final String? defWorkOut = jsonConvert.convert<String>(json['def_work_out']);
+  if (defWorkOut != null) {
+    tHAppliedEditEntity.defWorkOut = defWorkOut;
+  }
+  final String? adjustHours = jsonConvert.convert<String>(json['adjust_hours']);
+  if (adjustHours != null) {
+    tHAppliedEditEntity.adjustHours = adjustHours;
+  }
+  final String? subtractHours = jsonConvert.convert<String>(json['subtract_hours']);
+  if (subtractHours != null) {
+    tHAppliedEditEntity.subtractHours = subtractHours;
+  }
+  final List<String>? ballroomList = (json['ballroom_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<String>(e) as String).toList();
+  if (ballroomList != null) {
+    tHAppliedEditEntity.ballroomList = ballroomList;
+  }
+  final List<IndexOptionEntity>? statusList = (json['status_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<IndexOptionEntity>(e) as IndexOptionEntity).toList();
+  if (statusList != null) {
+    tHAppliedEditEntity.statusList = statusList;
+  }
+  final List<IndexOptionEntity>? reasonList = (json['reason_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<IndexOptionEntity>(e) as IndexOptionEntity).toList();
+  if (reasonList != null) {
+    tHAppliedEditEntity.reasonList = reasonList;
+  }
+  return tHAppliedEditEntity;
+}
+
+Map<String, dynamic> $THAppliedEditEntityToJson(THAppliedEditEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['applied'] = entity.applied?.toJson();
+  data['applied_id'] = entity.appliedId;
+  data['member_id'] = entity.memberId;
+  data['remark'] = entity.remark;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['default_start'] = entity.defaultStart;
+  data['default_end'] = entity.defaultEnd;
+  data['security_in'] = entity.securityIn;
+  data['def_security_in'] = entity.defSecurityIn;
+  data['security_out'] = entity.securityOut;
+  data['def_security_out'] = entity.defSecurityOut;
+  data['work_in'] = entity.workIn;
+  data['def_work_in'] = entity.defWorkIn;
+  data['work_out'] = entity.workOut;
+  data['def_work_out'] = entity.defWorkOut;
+  data['adjust_hours'] = entity.adjustHours;
+  data['subtract_hours'] = entity.subtractHours;
+  data['ballroom_list'] = entity.ballroomList;
+  data['status_list'] = entity.statusList.map((v) => v.toJson()).toList();
+  data['reason_list'] = entity.reasonList.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension THAppliedEditEntityExtension on THAppliedEditEntity {
+  THAppliedEditEntity copyWith({
+    THAppliedEditApplied? applied,
+    String? appliedId,
+    String? memberId,
+    String? remark,
+    String? startTime,
+    String? endTime,
+    String? defaultStart,
+    String? defaultEnd,
+    String? securityIn,
+    String? defSecurityIn,
+    String? securityOut,
+    String? defSecurityOut,
+    String? workIn,
+    String? defWorkIn,
+    String? workOut,
+    String? defWorkOut,
+    String? adjustHours,
+    String? subtractHours,
+    List<String>? ballroomList,
+    List<IndexOptionEntity>? statusList,
+    List<IndexOptionEntity>? reasonList,
+  }) {
+    return THAppliedEditEntity()
+      ..applied = applied ?? this.applied
+      ..appliedId = appliedId ?? this.appliedId
+      ..memberId = memberId ?? this.memberId
+      ..remark = remark ?? this.remark
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..defaultStart = defaultStart ?? this.defaultStart
+      ..defaultEnd = defaultEnd ?? this.defaultEnd
+      ..securityIn = securityIn ?? this.securityIn
+      ..defSecurityIn = defSecurityIn ?? this.defSecurityIn
+      ..securityOut = securityOut ?? this.securityOut
+      ..defSecurityOut = defSecurityOut ?? this.defSecurityOut
+      ..workIn = workIn ?? this.workIn
+      ..defWorkIn = defWorkIn ?? this.defWorkIn
+      ..workOut = workOut ?? this.workOut
+      ..defWorkOut = defWorkOut ?? this.defWorkOut
+      ..adjustHours = adjustHours ?? this.adjustHours
+      ..subtractHours = subtractHours ?? this.subtractHours
+      ..ballroomList = ballroomList ?? this.ballroomList
+      ..statusList = statusList ?? this.statusList
+      ..reasonList = reasonList ?? this.reasonList;
+  }
+}
+
+THAppliedEditApplied $THAppliedEditAppliedFromJson(Map<String, dynamic> json) {
+  final THAppliedEditApplied tHAppliedEditApplied = THAppliedEditApplied();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    tHAppliedEditApplied.id = id;
+  }
+  final String? jobId = jsonConvert.convert<String>(json['job_id']);
+  if (jobId != null) {
+    tHAppliedEditApplied.jobId = jobId;
+  }
+  final String? sId = jsonConvert.convert<String>(json['s_id']);
+  if (sId != null) {
+    tHAppliedEditApplied.sId = sId;
+  }
+  final String? memberId = jsonConvert.convert<String>(json['member_id']);
+  if (memberId != null) {
+    tHAppliedEditApplied.memberId = memberId;
+  }
+  final String? labourerId = jsonConvert.convert<String>(json['labourer_id']);
+  if (labourerId != null) {
+    tHAppliedEditApplied.labourerId = labourerId;
+  }
+  final String? labourerName = jsonConvert.convert<String>(json['labourer_name']);
+  if (labourerName != null) {
+    tHAppliedEditApplied.labourerName = labourerName;
+  }
+  final String? labourerNric = jsonConvert.convert<String>(json['labourer_nric']);
+  if (labourerNric != null) {
+    tHAppliedEditApplied.labourerNric = labourerNric;
+  }
+  final int? sourceType = jsonConvert.convert<int>(json['source_type']);
+  if (sourceType != null) {
+    tHAppliedEditApplied.sourceType = sourceType;
+  }
+  final String? employerId = jsonConvert.convert<String>(json['employer_id']);
+  if (employerId != null) {
+    tHAppliedEditApplied.employerId = employerId;
+  }
+  final String? employerName = jsonConvert.convert<String>(json['employer_name']);
+  if (employerName != null) {
+    tHAppliedEditApplied.employerName = employerName;
+  }
+  final String? agencyId = jsonConvert.convert<String>(json['agency_id']);
+  if (agencyId != null) {
+    tHAppliedEditApplied.agencyId = agencyId;
+  }
+  final String? agencyName = jsonConvert.convert<String>(json['agency_name']);
+  if (agencyName != null) {
+    tHAppliedEditApplied.agencyName = agencyName;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    tHAppliedEditApplied.jobTitle = jobTitle;
+  }
+  final String? outletId = jsonConvert.convert<String>(json['outlet_id']);
+  if (outletId != null) {
+    tHAppliedEditApplied.outletId = outletId;
+  }
+  final String? outletName = jsonConvert.convert<String>(json['outlet_name']);
+  if (outletName != null) {
+    tHAppliedEditApplied.outletName = outletName;
+  }
+  final String? ballroomId = jsonConvert.convert<String>(json['ballroom_id']);
+  if (ballroomId != null) {
+    tHAppliedEditApplied.ballroomId = ballroomId;
+  }
+  final String? ballroomName = jsonConvert.convert<String>(json['ballroom_name']);
+  if (ballroomName != null) {
+    tHAppliedEditApplied.ballroomName = ballroomName;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    tHAppliedEditApplied.jobDate = jobDate;
+  }
+  final int? startTime = jsonConvert.convert<int>(json['start_time']);
+  if (startTime != null) {
+    tHAppliedEditApplied.startTime = startTime;
+  }
+  final int? endTime = jsonConvert.convert<int>(json['end_time']);
+  if (endTime != null) {
+    tHAppliedEditApplied.endTime = endTime;
+  }
+  final String? workingHours = jsonConvert.convert<String>(json['working_hours']);
+  if (workingHours != null) {
+    tHAppliedEditApplied.workingHours = workingHours;
+  }
+  final String? adjustHours = jsonConvert.convert<String>(json['adjust_hours']);
+  if (adjustHours != null) {
+    tHAppliedEditApplied.adjustHours = adjustHours;
+  }
+  final String? totalHours = jsonConvert.convert<String>(json['total_hours']);
+  if (totalHours != null) {
+    tHAppliedEditApplied.totalHours = totalHours;
+  }
+  final String? hourlyRate = jsonConvert.convert<String>(json['hourly_rate']);
+  if (hourlyRate != null) {
+    tHAppliedEditApplied.hourlyRate = hourlyRate;
+  }
+  final String? grossWage = jsonConvert.convert<String>(json['gross_wage']);
+  if (grossWage != null) {
+    tHAppliedEditApplied.grossWage = grossWage;
+  }
+  final int? securityClockIn = jsonConvert.convert<int>(json['security_clock_in']);
+  if (securityClockIn != null) {
+    tHAppliedEditApplied.securityClockIn = securityClockIn;
+  }
+  final int? securityClockOut = jsonConvert.convert<int>(json['security_clock_out']);
+  if (securityClockOut != null) {
+    tHAppliedEditApplied.securityClockOut = securityClockOut;
+  }
+  final int? workClockIn = jsonConvert.convert<int>(json['work_clock_in']);
+  if (workClockIn != null) {
+    tHAppliedEditApplied.workClockIn = workClockIn;
+  }
+  final int? workClockOut = jsonConvert.convert<int>(json['work_clock_out']);
+  if (workClockOut != null) {
+    tHAppliedEditApplied.workClockOut = workClockOut;
+  }
+  final int? securityIn = jsonConvert.convert<int>(json['security_in']);
+  if (securityIn != null) {
+    tHAppliedEditApplied.securityIn = securityIn;
+  }
+  final int? securityOut = jsonConvert.convert<int>(json['security_out']);
+  if (securityOut != null) {
+    tHAppliedEditApplied.securityOut = securityOut;
+  }
+  final int? workIn = jsonConvert.convert<int>(json['work_in']);
+  if (workIn != null) {
+    tHAppliedEditApplied.workIn = workIn;
+  }
+  final int? workOut = jsonConvert.convert<int>(json['work_out']);
+  if (workOut != null) {
+    tHAppliedEditApplied.workOut = workOut;
+  }
+  final String? status = jsonConvert.convert<String>(json['status']);
+  if (status != null) {
+    tHAppliedEditApplied.status = status;
+  }
+  final int? remarkStatus = jsonConvert.convert<int>(json['remark_status']);
+  if (remarkStatus != null) {
+    tHAppliedEditApplied.remarkStatus = remarkStatus;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    tHAppliedEditApplied.createdAt = createdAt;
+  }
+  final String? updatedAt = jsonConvert.convert<String>(json['updated_at']);
+  if (updatedAt != null) {
+    tHAppliedEditApplied.updatedAt = updatedAt;
+  }
+  final int? syncPayroll = jsonConvert.convert<int>(json['sync_payroll']);
+  if (syncPayroll != null) {
+    tHAppliedEditApplied.syncPayroll = syncPayroll;
+  }
+  final String? signImage = jsonConvert.convert<String>(json['sign_image']);
+  if (signImage != null) {
+    tHAppliedEditApplied.signImage = signImage;
+  }
+  final String? eventName = jsonConvert.convert<String>(json['event_name']);
+  if (eventName != null) {
+    tHAppliedEditApplied.eventName = eventName;
+  }
+  final String? eventType = jsonConvert.convert<String>(json['event_type']);
+  if (eventType != null) {
+    tHAppliedEditApplied.eventType = eventType;
+  }
+  final int? workingType = jsonConvert.convert<int>(json['working_type']);
+  if (workingType != null) {
+    tHAppliedEditApplied.workingType = workingType;
+  }
+  final String? epfEmployer = jsonConvert.convert<String>(json['epf_employer']);
+  if (epfEmployer != null) {
+    tHAppliedEditApplied.epfEmployer = epfEmployer;
+  }
+  final String? epfEmployee = jsonConvert.convert<String>(json['epf_employee']);
+  if (epfEmployee != null) {
+    tHAppliedEditApplied.epfEmployee = epfEmployee;
+  }
+  final String? epfTotal = jsonConvert.convert<String>(json['epf_total']);
+  if (epfTotal != null) {
+    tHAppliedEditApplied.epfTotal = epfTotal;
+  }
+  final String? netPay = jsonConvert.convert<String>(json['net_pay']);
+  if (netPay != null) {
+    tHAppliedEditApplied.netPay = netPay;
+  }
+  final String? socso = jsonConvert.convert<String>(json['socso']);
+  if (socso != null) {
+    tHAppliedEditApplied.socso = socso;
+  }
+  final int? paymentStatus = jsonConvert.convert<int>(json['payment_status']);
+  if (paymentStatus != null) {
+    tHAppliedEditApplied.paymentStatus = paymentStatus;
+  }
+  final String? paidTime = jsonConvert.convert<String>(json['paid_time']);
+  if (paidTime != null) {
+    tHAppliedEditApplied.paidTime = paidTime;
+  }
+  final String? agencyRate = jsonConvert.convert<String>(json['agency_rate']);
+  if (agencyRate != null) {
+    tHAppliedEditApplied.agencyRate = agencyRate;
+  }
+  final String? agencyWage = jsonConvert.convert<String>(json['agency_wage']);
+  if (agencyWage != null) {
+    tHAppliedEditApplied.agencyWage = agencyWage;
+  }
+  final String? remark = jsonConvert.convert<String>(json['remark']);
+  if (remark != null) {
+    tHAppliedEditApplied.remark = remark;
+  }
+  final String? reasonType = jsonConvert.convert<String>(json['reason_type']);
+  if (reasonType != null) {
+    tHAppliedEditApplied.reasonType = reasonType;
+  }
+  final int? auditReject = jsonConvert.convert<int>(json['audit_reject']);
+  if (auditReject != null) {
+    tHAppliedEditApplied.auditReject = auditReject;
+  }
+  final String? reviseHours = jsonConvert.convert<String>(json['revise_hours']);
+  if (reviseHours != null) {
+    tHAppliedEditApplied.reviseHours = reviseHours;
+  }
+  final String? reviseGrossWage = jsonConvert.convert<String>(json['revise_gross_wage']);
+  if (reviseGrossWage != null) {
+    tHAppliedEditApplied.reviseGrossWage = reviseGrossWage;
+  }
+  final String? reviseAgencyWage = jsonConvert.convert<String>(json['revise_agency_wage']);
+  if (reviseAgencyWage != null) {
+    tHAppliedEditApplied.reviseAgencyWage = reviseAgencyWage;
+  }
+  final int? isOt = jsonConvert.convert<int>(json['is_ot']);
+  if (isOt != null) {
+    tHAppliedEditApplied.isOt = isOt;
+  }
+  final String? rejectMsg = jsonConvert.convert<String>(json['reject_msg']);
+  if (rejectMsg != null) {
+    tHAppliedEditApplied.rejectMsg = rejectMsg;
+  }
+  return tHAppliedEditApplied;
+}
+
+Map<String, dynamic> $THAppliedEditAppliedToJson(THAppliedEditApplied entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['job_id'] = entity.jobId;
+  data['s_id'] = entity.sId;
+  data['member_id'] = entity.memberId;
+  data['labourer_id'] = entity.labourerId;
+  data['labourer_name'] = entity.labourerName;
+  data['labourer_nric'] = entity.labourerNric;
+  data['source_type'] = entity.sourceType;
+  data['employer_id'] = entity.employerId;
+  data['employer_name'] = entity.employerName;
+  data['agency_id'] = entity.agencyId;
+  data['agency_name'] = entity.agencyName;
+  data['job_title'] = entity.jobTitle;
+  data['outlet_id'] = entity.outletId;
+  data['outlet_name'] = entity.outletName;
+  data['ballroom_id'] = entity.ballroomId;
+  data['ballroom_name'] = entity.ballroomName;
+  data['job_date'] = entity.jobDate;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['working_hours'] = entity.workingHours;
+  data['adjust_hours'] = entity.adjustHours;
+  data['total_hours'] = entity.totalHours;
+  data['hourly_rate'] = entity.hourlyRate;
+  data['gross_wage'] = entity.grossWage;
+  data['security_clock_in'] = entity.securityClockIn;
+  data['security_clock_out'] = entity.securityClockOut;
+  data['work_clock_in'] = entity.workClockIn;
+  data['work_clock_out'] = entity.workClockOut;
+  data['security_in'] = entity.securityIn;
+  data['security_out'] = entity.securityOut;
+  data['work_in'] = entity.workIn;
+  data['work_out'] = entity.workOut;
+  data['status'] = entity.status;
+  data['remark_status'] = entity.remarkStatus;
+  data['created_at'] = entity.createdAt;
+  data['updated_at'] = entity.updatedAt;
+  data['sync_payroll'] = entity.syncPayroll;
+  data['sign_image'] = entity.signImage;
+  data['event_name'] = entity.eventName;
+  data['event_type'] = entity.eventType;
+  data['working_type'] = entity.workingType;
+  data['epf_employer'] = entity.epfEmployer;
+  data['epf_employee'] = entity.epfEmployee;
+  data['epf_total'] = entity.epfTotal;
+  data['net_pay'] = entity.netPay;
+  data['socso'] = entity.socso;
+  data['payment_status'] = entity.paymentStatus;
+  data['paid_time'] = entity.paidTime;
+  data['agency_rate'] = entity.agencyRate;
+  data['agency_wage'] = entity.agencyWage;
+  data['remark'] = entity.remark;
+  data['reason_type'] = entity.reasonType;
+  data['audit_reject'] = entity.auditReject;
+  data['revise_hours'] = entity.reviseHours;
+  data['revise_gross_wage'] = entity.reviseGrossWage;
+  data['revise_agency_wage'] = entity.reviseAgencyWage;
+  data['is_ot'] = entity.isOt;
+  data['reject_msg'] = entity.rejectMsg;
+  return data;
+}
+
+extension THAppliedEditAppliedExtension on THAppliedEditApplied {
+  THAppliedEditApplied copyWith({
+    String? id,
+    String? jobId,
+    String? sId,
+    String? memberId,
+    String? labourerId,
+    String? labourerName,
+    String? labourerNric,
+    int? sourceType,
+    String? employerId,
+    String? employerName,
+    String? agencyId,
+    String? agencyName,
+    String? jobTitle,
+    String? outletId,
+    String? outletName,
+    String? ballroomId,
+    String? ballroomName,
+    String? jobDate,
+    int? startTime,
+    int? endTime,
+    String? workingHours,
+    String? adjustHours,
+    String? totalHours,
+    String? hourlyRate,
+    String? grossWage,
+    int? securityClockIn,
+    int? securityClockOut,
+    int? workClockIn,
+    int? workClockOut,
+    int? securityIn,
+    int? securityOut,
+    int? workIn,
+    int? workOut,
+    String? status,
+    int? remarkStatus,
+    String? createdAt,
+    String? updatedAt,
+    int? syncPayroll,
+    String? signImage,
+    String? eventName,
+    String? eventType,
+    int? workingType,
+    String? epfEmployer,
+    String? epfEmployee,
+    String? epfTotal,
+    String? netPay,
+    String? socso,
+    int? paymentStatus,
+    String? paidTime,
+    String? agencyRate,
+    String? agencyWage,
+    String? remark,
+    String? reasonType,
+    int? auditReject,
+    String? reviseHours,
+    String? reviseGrossWage,
+    String? reviseAgencyWage,
+    int? isOt,
+    String? rejectMsg,
+  }) {
+    return THAppliedEditApplied()
+      ..id = id ?? this.id
+      ..jobId = jobId ?? this.jobId
+      ..sId = sId ?? this.sId
+      ..memberId = memberId ?? this.memberId
+      ..labourerId = labourerId ?? this.labourerId
+      ..labourerName = labourerName ?? this.labourerName
+      ..labourerNric = labourerNric ?? this.labourerNric
+      ..sourceType = sourceType ?? this.sourceType
+      ..employerId = employerId ?? this.employerId
+      ..employerName = employerName ?? this.employerName
+      ..agencyId = agencyId ?? this.agencyId
+      ..agencyName = agencyName ?? this.agencyName
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..outletId = outletId ?? this.outletId
+      ..outletName = outletName ?? this.outletName
+      ..ballroomId = ballroomId ?? this.ballroomId
+      ..ballroomName = ballroomName ?? this.ballroomName
+      ..jobDate = jobDate ?? this.jobDate
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..workingHours = workingHours ?? this.workingHours
+      ..adjustHours = adjustHours ?? this.adjustHours
+      ..totalHours = totalHours ?? this.totalHours
+      ..hourlyRate = hourlyRate ?? this.hourlyRate
+      ..grossWage = grossWage ?? this.grossWage
+      ..securityClockIn = securityClockIn ?? this.securityClockIn
+      ..securityClockOut = securityClockOut ?? this.securityClockOut
+      ..workClockIn = workClockIn ?? this.workClockIn
+      ..workClockOut = workClockOut ?? this.workClockOut
+      ..securityIn = securityIn ?? this.securityIn
+      ..securityOut = securityOut ?? this.securityOut
+      ..workIn = workIn ?? this.workIn
+      ..workOut = workOut ?? this.workOut
+      ..status = status ?? this.status
+      ..remarkStatus = remarkStatus ?? this.remarkStatus
+      ..createdAt = createdAt ?? this.createdAt
+      ..updatedAt = updatedAt ?? this.updatedAt
+      ..syncPayroll = syncPayroll ?? this.syncPayroll
+      ..signImage = signImage ?? this.signImage
+      ..eventName = eventName ?? this.eventName
+      ..eventType = eventType ?? this.eventType
+      ..workingType = workingType ?? this.workingType
+      ..epfEmployer = epfEmployer ?? this.epfEmployer
+      ..epfEmployee = epfEmployee ?? this.epfEmployee
+      ..epfTotal = epfTotal ?? this.epfTotal
+      ..netPay = netPay ?? this.netPay
+      ..socso = socso ?? this.socso
+      ..paymentStatus = paymentStatus ?? this.paymentStatus
+      ..paidTime = paidTime ?? this.paidTime
+      ..agencyRate = agencyRate ?? this.agencyRate
+      ..agencyWage = agencyWage ?? this.agencyWage
+      ..remark = remark ?? this.remark
+      ..reasonType = reasonType ?? this.reasonType
+      ..auditReject = auditReject ?? this.auditReject
+      ..reviseHours = reviseHours ?? this.reviseHours
+      ..reviseGrossWage = reviseGrossWage ?? this.reviseGrossWage
+      ..reviseAgencyWage = reviseAgencyWage ?? this.reviseAgencyWage
+      ..isOt = isOt ?? this.isOt
+      ..rejectMsg = rejectMsg ?? this.rejectMsg;
+  }
+}

+ 114 - 0
packages/cs_domain/lib/generated/json/t_h_applied_employee_entity.g.dart

@@ -0,0 +1,114 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_applied_employee_entity.dart';
+
+THAppliedEmployeeEntity $THAppliedEmployeeEntityFromJson(Map<String, dynamic> json) {
+  final THAppliedEmployeeEntity tHAppliedEmployeeEntity = THAppliedEmployeeEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    tHAppliedEmployeeEntity.total = total;
+  }
+  final List<THAppliedEmployeeRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<THAppliedEmployeeRows>(e) as THAppliedEmployeeRows).toList();
+  if (rows != null) {
+    tHAppliedEmployeeEntity.rows = rows;
+  }
+  return tHAppliedEmployeeEntity;
+}
+
+Map<String, dynamic> $THAppliedEmployeeEntityToJson(THAppliedEmployeeEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension THAppliedEmployeeEntityExtension on THAppliedEmployeeEntity {
+  THAppliedEmployeeEntity copyWith({
+    int? total,
+    List<THAppliedEmployeeRows>? rows,
+  }) {
+    return THAppliedEmployeeEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+THAppliedEmployeeRows $THAppliedEmployeeRowsFromJson(Map<String, dynamic> json) {
+  final THAppliedEmployeeRows tHAppliedEmployeeRows = THAppliedEmployeeRows();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    tHAppliedEmployeeRows.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    tHAppliedEmployeeRows.name = name;
+  }
+  final String? gender = jsonConvert.convert<String>(json['gender']);
+  if (gender != null) {
+    tHAppliedEmployeeRows.gender = gender;
+  }
+  final String? mobile = jsonConvert.convert<String>(json['mobile']);
+  if (mobile != null) {
+    tHAppliedEmployeeRows.mobile = mobile;
+  }
+  final String? nric = jsonConvert.convert<String>(json['nric']);
+  if (nric != null) {
+    tHAppliedEmployeeRows.nric = nric;
+  }
+  final String? profilePicture = jsonConvert.convert<String>(json['profile_picture']);
+  if (profilePicture != null) {
+    tHAppliedEmployeeRows.profilePicture = profilePicture;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    tHAppliedEmployeeRows.status = status;
+  }
+  final int? applyState = jsonConvert.convert<int>(json['apply_state']);
+  if (applyState != null) {
+    tHAppliedEmployeeRows.applyState = applyState;
+  }
+  final bool? isSelected = jsonConvert.convert<bool>(json['isSelected']);
+  if (isSelected != null) {
+    tHAppliedEmployeeRows.isSelected = isSelected;
+  }
+  return tHAppliedEmployeeRows;
+}
+
+Map<String, dynamic> $THAppliedEmployeeRowsToJson(THAppliedEmployeeRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['gender'] = entity.gender;
+  data['mobile'] = entity.mobile;
+  data['nric'] = entity.nric;
+  data['profile_picture'] = entity.profilePicture;
+  data['status'] = entity.status;
+  data['apply_state'] = entity.applyState;
+  data['isSelected'] = entity.isSelected;
+  return data;
+}
+
+extension THAppliedEmployeeRowsExtension on THAppliedEmployeeRows {
+  THAppliedEmployeeRows copyWith({
+    String? id,
+    String? name,
+    String? gender,
+    String? mobile,
+    String? nric,
+    String? profilePicture,
+    int? status,
+    int? applyState,
+    bool? isSelected,
+  }) {
+    return THAppliedEmployeeRows()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..gender = gender ?? this.gender
+      ..mobile = mobile ?? this.mobile
+      ..nric = nric ?? this.nric
+      ..profilePicture = profilePicture ?? this.profilePicture
+      ..status = status ?? this.status
+      ..applyState = applyState ?? this.applyState
+      ..isSelected = isSelected ?? this.isSelected;
+  }
+}

+ 340 - 0
packages/cs_domain/lib/generated/json/t_h_applied_index_entity.g.dart

@@ -0,0 +1,340 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_applied_index_entity.dart';
+import 'package:domain/entity/response/index_option_entity.dart';
+
+
+THAppliedIndexEntity $THAppliedIndexEntityFromJson(Map<String, dynamic> json) {
+  final THAppliedIndexEntity tHAppliedIndexEntity = THAppliedIndexEntity();
+  final String? jobId = jsonConvert.convert<String>(json['job_id']);
+  if (jobId != null) {
+    tHAppliedIndexEntity.jobId = jobId;
+  }
+  final THAppliedIndexJob? job = jsonConvert.convert<THAppliedIndexJob>(json['job']);
+  if (job != null) {
+    tHAppliedIndexEntity.job = job;
+  }
+  final List<IndexOptionEntity>? statusList = (json['status_list'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<IndexOptionEntity>(e) as IndexOptionEntity).toList();
+  if (statusList != null) {
+    tHAppliedIndexEntity.statusList = statusList;
+  }
+  final bool? canAppend = jsonConvert.convert<bool>(json['can_append']);
+  if (canAppend != null) {
+    tHAppliedIndexEntity.canAppend = canAppend;
+  }
+  final String? sourceShow = jsonConvert.convert<String>(json['source_show']);
+  if (sourceShow != null) {
+    tHAppliedIndexEntity.sourceShow = sourceShow;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    tHAppliedIndexEntity.jobDate = jobDate;
+  }
+  final bool? isSuper = jsonConvert.convert<bool>(json['is_super']);
+  if (isSuper != null) {
+    tHAppliedIndexEntity.isSuper = isSuper;
+  }
+  return tHAppliedIndexEntity;
+}
+
+Map<String, dynamic> $THAppliedIndexEntityToJson(THAppliedIndexEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['job_id'] = entity.jobId;
+  data['job'] = entity.job?.toJson();
+  data['status_list'] = entity.statusList.map((v) => v.toJson()).toList();
+  data['can_append'] = entity.canAppend;
+  data['source_show'] = entity.sourceShow;
+  data['job_date'] = entity.jobDate;
+  data['is_super'] = entity.isSuper;
+  return data;
+}
+
+extension THAppliedIndexEntityExtension on THAppliedIndexEntity {
+  THAppliedIndexEntity copyWith({
+    String? jobId,
+    THAppliedIndexJob? job,
+    List<IndexOptionEntity>? statusList,
+    bool? canAppend,
+    String? sourceShow,
+    String? jobDate,
+    bool? isSuper,
+  }) {
+    return THAppliedIndexEntity()
+      ..jobId = jobId ?? this.jobId
+      ..job = job ?? this.job
+      ..statusList = statusList ?? this.statusList
+      ..canAppend = canAppend ?? this.canAppend
+      ..sourceShow = sourceShow ?? this.sourceShow
+      ..jobDate = jobDate ?? this.jobDate
+      ..isSuper = isSuper ?? this.isSuper;
+  }
+}
+
+THAppliedIndexJob $THAppliedIndexJobFromJson(Map<String, dynamic> json) {
+  final THAppliedIndexJob tHAppliedIndexJob = THAppliedIndexJob();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    tHAppliedIndexJob.id = id;
+  }
+  final String? employerId = jsonConvert.convert<String>(json['employer_id']);
+  if (employerId != null) {
+    tHAppliedIndexJob.employerId = employerId;
+  }
+  final String? employerName = jsonConvert.convert<String>(json['employer_name']);
+  if (employerName != null) {
+    tHAppliedIndexJob.employerName = employerName;
+  }
+  final String? eAdminId = jsonConvert.convert<String>(json['e_admin_id']);
+  if (eAdminId != null) {
+    tHAppliedIndexJob.eAdminId = eAdminId;
+  }
+  final String? yyJobId = jsonConvert.convert<String>(json['yy_job_id']);
+  if (yyJobId != null) {
+    tHAppliedIndexJob.yyJobId = yyJobId;
+  }
+  final String? sourceType = jsonConvert.convert<String>(json['source_type']);
+  if (sourceType != null) {
+    tHAppliedIndexJob.sourceType = sourceType;
+  }
+  final String? agencyId = jsonConvert.convert<String>(json['agency_id']);
+  if (agencyId != null) {
+    tHAppliedIndexJob.agencyId = agencyId;
+  }
+  final String? agencyName = jsonConvert.convert<String>(json['agency_name']);
+  if (agencyName != null) {
+    tHAppliedIndexJob.agencyName = agencyName;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    tHAppliedIndexJob.jobTitle = jobTitle;
+  }
+  final String? outletId = jsonConvert.convert<String>(json['outlet_id']);
+  if (outletId != null) {
+    tHAppliedIndexJob.outletId = outletId;
+  }
+  final String? outletName = jsonConvert.convert<String>(json['outlet_name']);
+  if (outletName != null) {
+    tHAppliedIndexJob.outletName = outletName;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    tHAppliedIndexJob.jobDate = jobDate;
+  }
+  final int? startTime = jsonConvert.convert<int>(json['start_time']);
+  if (startTime != null) {
+    tHAppliedIndexJob.startTime = startTime;
+  }
+  final int? endTime = jsonConvert.convert<int>(json['end_time']);
+  if (endTime != null) {
+    tHAppliedIndexJob.endTime = endTime;
+  }
+  final String? workingHours = jsonConvert.convert<String>(json['working_hours']);
+  if (workingHours != null) {
+    tHAppliedIndexJob.workingHours = workingHours;
+  }
+  final String? hourlyRate = jsonConvert.convert<String>(json['hourly_rate']);
+  if (hourlyRate != null) {
+    tHAppliedIndexJob.hourlyRate = hourlyRate;
+  }
+  final String? hiringNum = jsonConvert.convert<String>(json['hiring_num']);
+  if (hiringNum != null) {
+    tHAppliedIndexJob.hiringNum = hiringNum;
+  }
+  final String? realNum = jsonConvert.convert<String>(json['real_num']);
+  if (realNum != null) {
+    tHAppliedIndexJob.realNum = realNum;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    tHAppliedIndexJob.status = status;
+  }
+  final String? description = jsonConvert.convert<String>(json['description']);
+  if (description != null) {
+    tHAppliedIndexJob.description = description;
+  }
+  final int? confirmStatus = jsonConvert.convert<int>(json['confirm_status']);
+  if (confirmStatus != null) {
+    tHAppliedIndexJob.confirmStatus = confirmStatus;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    tHAppliedIndexJob.createdAt = createdAt;
+  }
+  final String? updatedAt = jsonConvert.convert<String>(json['updated_at']);
+  if (updatedAt != null) {
+    tHAppliedIndexJob.updatedAt = updatedAt;
+  }
+  final String? deletedAt = jsonConvert.convert<String>(json['deleted_at']);
+  if (deletedAt != null) {
+    tHAppliedIndexJob.deletedAt = deletedAt;
+  }
+  final String? eventName = jsonConvert.convert<String>(json['event_name']);
+  if (eventName != null) {
+    tHAppliedIndexJob.eventName = eventName;
+  }
+  final String? eventType = jsonConvert.convert<String>(json['event_type']);
+  if (eventType != null) {
+    tHAppliedIndexJob.eventType = eventType;
+  }
+  final String? withTyphoid = jsonConvert.convert<String>(json['with_typhoid']);
+  if (withTyphoid != null) {
+    tHAppliedIndexJob.withTyphoid = withTyphoid;
+  }
+  final String? syncPayroll = jsonConvert.convert<String>(json['sync_payroll']);
+  if (syncPayroll != null) {
+    tHAppliedIndexJob.syncPayroll = syncPayroll;
+  }
+  final String? agencyRate = jsonConvert.convert<String>(json['agency_rate']);
+  if (agencyRate != null) {
+    tHAppliedIndexJob.agencyRate = agencyRate;
+  }
+  final String? requestId = jsonConvert.convert<String>(json['request_id']);
+  if (requestId != null) {
+    tHAppliedIndexJob.requestId = requestId;
+  }
+  final String? jobTitleId = jsonConvert.convert<String>(json['job_title_id']);
+  if (jobTitleId != null) {
+    tHAppliedIndexJob.jobTitleId = jobTitleId;
+  }
+  final int? isOt = jsonConvert.convert<int>(json['is_ot']);
+  if (isOt != null) {
+    tHAppliedIndexJob.isOt = isOt;
+  }
+  final String? positionId = jsonConvert.convert<String>(json['position_id']);
+  if (positionId != null) {
+    tHAppliedIndexJob.positionId = positionId;
+  }
+  final int? sexLimit = jsonConvert.convert<int>(json['sex_limit']);
+  if (sexLimit != null) {
+    tHAppliedIndexJob.sexLimit = sexLimit;
+  }
+  final String? maleLimit = jsonConvert.convert<String>(json['male_limit']);
+  if (maleLimit != null) {
+    tHAppliedIndexJob.maleLimit = maleLimit;
+  }
+  final String? femaleLimit = jsonConvert.convert<String>(json['female_limit']);
+  if (femaleLimit != null) {
+    tHAppliedIndexJob.femaleLimit = femaleLimit;
+  }
+  return tHAppliedIndexJob;
+}
+
+Map<String, dynamic> $THAppliedIndexJobToJson(THAppliedIndexJob entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['employer_id'] = entity.employerId;
+  data['employer_name'] = entity.employerName;
+  data['e_admin_id'] = entity.eAdminId;
+  data['yy_job_id'] = entity.yyJobId;
+  data['source_type'] = entity.sourceType;
+  data['agency_id'] = entity.agencyId;
+  data['agency_name'] = entity.agencyName;
+  data['job_title'] = entity.jobTitle;
+  data['outlet_id'] = entity.outletId;
+  data['outlet_name'] = entity.outletName;
+  data['job_date'] = entity.jobDate;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['working_hours'] = entity.workingHours;
+  data['hourly_rate'] = entity.hourlyRate;
+  data['hiring_num'] = entity.hiringNum;
+  data['real_num'] = entity.realNum;
+  data['status'] = entity.status;
+  data['description'] = entity.description;
+  data['confirm_status'] = entity.confirmStatus;
+  data['created_at'] = entity.createdAt;
+  data['updated_at'] = entity.updatedAt;
+  data['deleted_at'] = entity.deletedAt;
+  data['event_name'] = entity.eventName;
+  data['event_type'] = entity.eventType;
+  data['with_typhoid'] = entity.withTyphoid;
+  data['sync_payroll'] = entity.syncPayroll;
+  data['agency_rate'] = entity.agencyRate;
+  data['request_id'] = entity.requestId;
+  data['job_title_id'] = entity.jobTitleId;
+  data['is_ot'] = entity.isOt;
+  data['position_id'] = entity.positionId;
+  data['sex_limit'] = entity.sexLimit;
+  data['male_limit'] = entity.maleLimit;
+  data['female_limit'] = entity.femaleLimit;
+  return data;
+}
+
+extension THAppliedIndexJobExtension on THAppliedIndexJob {
+  THAppliedIndexJob copyWith({
+    String? id,
+    String? employerId,
+    String? employerName,
+    String? eAdminId,
+    String? yyJobId,
+    String? sourceType,
+    String? agencyId,
+    String? agencyName,
+    String? jobTitle,
+    String? outletId,
+    String? outletName,
+    String? jobDate,
+    int? startTime,
+    int? endTime,
+    String? workingHours,
+    String? hourlyRate,
+    String? hiringNum,
+    String? realNum,
+    int? status,
+    String? description,
+    int? confirmStatus,
+    String? createdAt,
+    String? updatedAt,
+    String? deletedAt,
+    String? eventName,
+    String? eventType,
+    String? withTyphoid,
+    String? syncPayroll,
+    String? agencyRate,
+    String? requestId,
+    String? jobTitleId,
+    int? isOt,
+    String? positionId,
+    int? sexLimit,
+    String? maleLimit,
+    String? femaleLimit,
+  }) {
+    return THAppliedIndexJob()
+      ..id = id ?? this.id
+      ..employerId = employerId ?? this.employerId
+      ..employerName = employerName ?? this.employerName
+      ..eAdminId = eAdminId ?? this.eAdminId
+      ..yyJobId = yyJobId ?? this.yyJobId
+      ..sourceType = sourceType ?? this.sourceType
+      ..agencyId = agencyId ?? this.agencyId
+      ..agencyName = agencyName ?? this.agencyName
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..outletId = outletId ?? this.outletId
+      ..outletName = outletName ?? this.outletName
+      ..jobDate = jobDate ?? this.jobDate
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..workingHours = workingHours ?? this.workingHours
+      ..hourlyRate = hourlyRate ?? this.hourlyRate
+      ..hiringNum = hiringNum ?? this.hiringNum
+      ..realNum = realNum ?? this.realNum
+      ..status = status ?? this.status
+      ..description = description ?? this.description
+      ..confirmStatus = confirmStatus ?? this.confirmStatus
+      ..createdAt = createdAt ?? this.createdAt
+      ..updatedAt = updatedAt ?? this.updatedAt
+      ..deletedAt = deletedAt ?? this.deletedAt
+      ..eventName = eventName ?? this.eventName
+      ..eventType = eventType ?? this.eventType
+      ..withTyphoid = withTyphoid ?? this.withTyphoid
+      ..syncPayroll = syncPayroll ?? this.syncPayroll
+      ..agencyRate = agencyRate ?? this.agencyRate
+      ..requestId = requestId ?? this.requestId
+      ..jobTitleId = jobTitleId ?? this.jobTitleId
+      ..isOt = isOt ?? this.isOt
+      ..positionId = positionId ?? this.positionId
+      ..sexLimit = sexLimit ?? this.sexLimit
+      ..maleLimit = maleLimit ?? this.maleLimit
+      ..femaleLimit = femaleLimit ?? this.femaleLimit;
+  }
+}

+ 306 - 0
packages/cs_domain/lib/generated/json/t_h_applied_table_entity.g.dart

@@ -0,0 +1,306 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_applied_table_entity.dart';
+
+THAppliedTableEntity $THAppliedTableEntityFromJson(Map<String, dynamic> json) {
+  final THAppliedTableEntity tHAppliedTableEntity = THAppliedTableEntity();
+  final int? total = jsonConvert.convert<int>(json['total']);
+  if (total != null) {
+    tHAppliedTableEntity.total = total;
+  }
+  final List<THAppliedTableRows>? rows = (json['rows'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<THAppliedTableRows>(e) as THAppliedTableRows).toList();
+  if (rows != null) {
+    tHAppliedTableEntity.rows = rows;
+  }
+  return tHAppliedTableEntity;
+}
+
+Map<String, dynamic> $THAppliedTableEntityToJson(THAppliedTableEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['total'] = entity.total;
+  data['rows'] = entity.rows.map((v) => v.toJson()).toList();
+  return data;
+}
+
+extension THAppliedTableEntityExtension on THAppliedTableEntity {
+  THAppliedTableEntity copyWith({
+    int? total,
+    List<THAppliedTableRows>? rows,
+  }) {
+    return THAppliedTableEntity()
+      ..total = total ?? this.total
+      ..rows = rows ?? this.rows;
+  }
+}
+
+THAppliedTableRows $THAppliedTableRowsFromJson(Map<String, dynamic> json) {
+  final THAppliedTableRows tHAppliedTableRows = THAppliedTableRows();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    tHAppliedTableRows.id = id;
+  }
+  final String? memberId = jsonConvert.convert<String>(json['member_id']);
+  if (memberId != null) {
+    tHAppliedTableRows.memberId = memberId;
+  }
+  final String? sId = jsonConvert.convert<String>(json['s_id']);
+  if (sId != null) {
+    tHAppliedTableRows.sId = sId;
+  }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    tHAppliedTableRows.jobTitle = jobTitle;
+  }
+  final String? outletName = jsonConvert.convert<String>(json['outlet_name']);
+  if (outletName != null) {
+    tHAppliedTableRows.outletName = outletName;
+  }
+  final String? ballroomName = jsonConvert.convert<String>(json['ballroom_name']);
+  if (ballroomName != null) {
+    tHAppliedTableRows.ballroomName = ballroomName;
+  }
+  final String? labourerName = jsonConvert.convert<String>(json['labourer_name']);
+  if (labourerName != null) {
+    tHAppliedTableRows.labourerName = labourerName;
+  }
+  final String? labourerNric = jsonConvert.convert<String>(json['labourer_nric']);
+  if (labourerNric != null) {
+    tHAppliedTableRows.labourerNric = labourerNric;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    tHAppliedTableRows.jobDate = jobDate;
+  }
+  final String? startTime = jsonConvert.convert<String>(json['start_time']);
+  if (startTime != null) {
+    tHAppliedTableRows.startTime = startTime;
+  }
+  final String? endTime = jsonConvert.convert<String>(json['end_time']);
+  if (endTime != null) {
+    tHAppliedTableRows.endTime = endTime;
+  }
+  final String? adjustHours = jsonConvert.convert<String>(json['adjust_hours']);
+  if (adjustHours != null) {
+    tHAppliedTableRows.adjustHours = adjustHours;
+  }
+  final String? workingHours = jsonConvert.convert<String>(json['working_hours']);
+  if (workingHours != null) {
+    tHAppliedTableRows.workingHours = workingHours;
+  }
+  final String? totalHours = jsonConvert.convert<String>(json['total_hours']);
+  if (totalHours != null) {
+    tHAppliedTableRows.totalHours = totalHours;
+  }
+  final int? status = jsonConvert.convert<int>(json['status']);
+  if (status != null) {
+    tHAppliedTableRows.status = status;
+  }
+  final String? statusShow = jsonConvert.convert<String>(json['status_show']);
+  if (statusShow != null) {
+    tHAppliedTableRows.statusShow = statusShow;
+  }
+  final String? hourlyRate = jsonConvert.convert<String>(json['hourly_rate']);
+  if (hourlyRate != null) {
+    tHAppliedTableRows.hourlyRate = hourlyRate;
+  }
+  final String? remarkStatus = jsonConvert.convert<String>(json['remark_status']);
+  if (remarkStatus != null) {
+    tHAppliedTableRows.remarkStatus = remarkStatus;
+  }
+  final THAppliedTableCheckInOut? securityIn = jsonConvert.convert<THAppliedTableCheckInOut>(json['security_in']);
+  if (securityIn != null) {
+    tHAppliedTableRows.securityIn = securityIn;
+  }
+  final THAppliedTableCheckInOut? securityOut = jsonConvert.convert<THAppliedTableCheckInOut>(json['security_out']);
+  if (securityOut != null) {
+    tHAppliedTableRows.securityOut = securityOut;
+  }
+  final THAppliedTableCheckInOut? workIn = jsonConvert.convert<THAppliedTableCheckInOut>(json['work_in']);
+  if (workIn != null) {
+    tHAppliedTableRows.workIn = workIn;
+  }
+  final THAppliedTableCheckInOut? workOut = jsonConvert.convert<THAppliedTableCheckInOut>(json['work_out']);
+  if (workOut != null) {
+    tHAppliedTableRows.workOut = workOut;
+  }
+  final String? sIn = jsonConvert.convert<String>(json['s_in']);
+  if (sIn != null) {
+    tHAppliedTableRows.sIn = sIn;
+  }
+  final String? sOut = jsonConvert.convert<String>(json['s_out']);
+  if (sOut != null) {
+    tHAppliedTableRows.sOut = sOut;
+  }
+  final String? wIn = jsonConvert.convert<String>(json['w_in']);
+  if (wIn != null) {
+    tHAppliedTableRows.wIn = wIn;
+  }
+  final String? wOut = jsonConvert.convert<String>(json['w_out']);
+  if (wOut != null) {
+    tHAppliedTableRows.wOut = wOut;
+  }
+  final String? auditReject = jsonConvert.convert<String>(json['audit_reject']);
+  if (auditReject != null) {
+    tHAppliedTableRows.auditReject = auditReject;
+  }
+  final String? reviseHours = jsonConvert.convert<String>(json['revise_hours']);
+  if (reviseHours != null) {
+    tHAppliedTableRows.reviseHours = reviseHours;
+  }
+  final String? clothingSize = jsonConvert.convert<String>(json['clothing_size']);
+  if (clothingSize != null) {
+    tHAppliedTableRows.clothingSize = clothingSize;
+  }
+  final bool? isSelected = jsonConvert.convert<bool>(json['isSelected']);
+  if (isSelected != null) {
+    tHAppliedTableRows.isSelected = isSelected;
+  }
+  return tHAppliedTableRows;
+}
+
+Map<String, dynamic> $THAppliedTableRowsToJson(THAppliedTableRows entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['member_id'] = entity.memberId;
+  data['s_id'] = entity.sId;
+  data['job_title'] = entity.jobTitle;
+  data['outlet_name'] = entity.outletName;
+  data['ballroom_name'] = entity.ballroomName;
+  data['labourer_name'] = entity.labourerName;
+  data['labourer_nric'] = entity.labourerNric;
+  data['job_date'] = entity.jobDate;
+  data['start_time'] = entity.startTime;
+  data['end_time'] = entity.endTime;
+  data['adjust_hours'] = entity.adjustHours;
+  data['working_hours'] = entity.workingHours;
+  data['total_hours'] = entity.totalHours;
+  data['status'] = entity.status;
+  data['status_show'] = entity.statusShow;
+  data['hourly_rate'] = entity.hourlyRate;
+  data['remark_status'] = entity.remarkStatus;
+  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['audit_reject'] = entity.auditReject;
+  data['revise_hours'] = entity.reviseHours;
+  data['clothing_size'] = entity.clothingSize;
+  data['isSelected'] = entity.isSelected;
+  return data;
+}
+
+extension THAppliedTableRowsExtension on THAppliedTableRows {
+  THAppliedTableRows copyWith({
+    String? id,
+    String? memberId,
+    String? sId,
+    String? jobTitle,
+    String? outletName,
+    String? ballroomName,
+    String? labourerName,
+    String? labourerNric,
+    String? jobDate,
+    String? startTime,
+    String? endTime,
+    String? adjustHours,
+    String? workingHours,
+    String? totalHours,
+    int? status,
+    String? statusShow,
+    String? hourlyRate,
+    String? remarkStatus,
+    THAppliedTableCheckInOut? securityIn,
+    THAppliedTableCheckInOut? securityOut,
+    THAppliedTableCheckInOut? workIn,
+    THAppliedTableCheckInOut? workOut,
+    String? sIn,
+    String? sOut,
+    String? wIn,
+    String? wOut,
+    String? auditReject,
+    String? reviseHours,
+    String? clothingSize,
+    bool? isSelected,
+  }) {
+    return THAppliedTableRows()
+      ..id = id ?? this.id
+      ..memberId = memberId ?? this.memberId
+      ..sId = sId ?? this.sId
+      ..jobTitle = jobTitle ?? this.jobTitle
+      ..outletName = outletName ?? this.outletName
+      ..ballroomName = ballroomName ?? this.ballroomName
+      ..labourerName = labourerName ?? this.labourerName
+      ..labourerNric = labourerNric ?? this.labourerNric
+      ..jobDate = jobDate ?? this.jobDate
+      ..startTime = startTime ?? this.startTime
+      ..endTime = endTime ?? this.endTime
+      ..adjustHours = adjustHours ?? this.adjustHours
+      ..workingHours = workingHours ?? this.workingHours
+      ..totalHours = totalHours ?? this.totalHours
+      ..status = status ?? this.status
+      ..statusShow = statusShow ?? this.statusShow
+      ..hourlyRate = hourlyRate ?? this.hourlyRate
+      ..remarkStatus = remarkStatus ?? this.remarkStatus
+      ..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
+      ..auditReject = auditReject ?? this.auditReject
+      ..reviseHours = reviseHours ?? this.reviseHours
+      ..clothingSize = clothingSize ?? this.clothingSize
+      ..isSelected = isSelected ?? this.isSelected;
+  }
+}
+
+THAppliedTableCheckInOut $THAppliedTableCheckInOutFromJson(Map<String, dynamic> json) {
+  final THAppliedTableCheckInOut tHAppliedTableCheckInOut = THAppliedTableCheckInOut();
+  final String? time = jsonConvert.convert<String>(json['time']);
+  if (time != null) {
+    tHAppliedTableCheckInOut.time = time;
+  }
+  final String? temp = jsonConvert.convert<String>(json['temp']);
+  if (temp != null) {
+    tHAppliedTableCheckInOut.temp = temp;
+  }
+  final String? image = jsonConvert.convert<String>(json['image']);
+  if (image != null) {
+    tHAppliedTableCheckInOut.image = image;
+  }
+  final int? changed = jsonConvert.convert<int>(json['changed']);
+  if (changed != null) {
+    tHAppliedTableCheckInOut.changed = changed;
+  }
+  return tHAppliedTableCheckInOut;
+}
+
+Map<String, dynamic> $THAppliedTableCheckInOutToJson(THAppliedTableCheckInOut entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['time'] = entity.time;
+  data['temp'] = entity.temp;
+  data['image'] = entity.image;
+  data['changed'] = entity.changed;
+  return data;
+}
+
+extension THAppliedTableCheckInOutExtension on THAppliedTableCheckInOut {
+  THAppliedTableCheckInOut copyWith({
+    String? time,
+    String? temp,
+    String? image,
+    int? changed,
+  }) {
+    return THAppliedTableCheckInOut()
+      ..time = time ?? this.time
+      ..temp = temp ?? this.temp
+      ..image = image ?? this.image
+      ..changed = changed ?? this.changed;
+  }
+}

+ 284 - 0
packages/cs_domain/lib/generated/json/t_h_employee_detail_entity.g.dart

@@ -0,0 +1,284 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_employee_detail_entity.dart';
+
+THEmployeeDetailEntity $THEmployeeDetailEntityFromJson(Map<String, dynamic> json) {
+  final THEmployeeDetailEntity tHEmployeeDetailEntity = THEmployeeDetailEntity();
+  final String? memberId = jsonConvert.convert<String>(json['member_id']);
+  if (memberId != null) {
+    tHEmployeeDetailEntity.memberId = memberId;
+  }
+  final String? staffId = jsonConvert.convert<String>(json['staff_id']);
+  if (staffId != null) {
+    tHEmployeeDetailEntity.staffId = staffId;
+  }
+  final THEmployeeDetailStaff? staff = jsonConvert.convert<THEmployeeDetailStaff>(json['staff']);
+  if (staff != null) {
+    tHEmployeeDetailEntity.staff = staff;
+  }
+  final String? workerName = jsonConvert.convert<String>(json['worker_name']);
+  if (workerName != null) {
+    tHEmployeeDetailEntity.workerName = workerName;
+  }
+  final String? mobile = jsonConvert.convert<String>(json['mobile']);
+  if (mobile != null) {
+    tHEmployeeDetailEntity.mobile = mobile;
+  }
+  final String? icon = jsonConvert.convert<String>(json['icon']);
+  if (icon != null) {
+    tHEmployeeDetailEntity.icon = icon;
+  }
+  final String? sex = jsonConvert.convert<String>(json['sex']);
+  if (sex != null) {
+    tHEmployeeDetailEntity.sex = sex;
+  }
+  final String? nric = jsonConvert.convert<String>(json['nric']);
+  if (nric != null) {
+    tHEmployeeDetailEntity.nric = nric;
+  }
+  final String? hourlyRate = jsonConvert.convert<String>(json['hourly_rate']);
+  if (hourlyRate != null) {
+    tHEmployeeDetailEntity.hourlyRate = hourlyRate;
+  }
+  final String? clothingSize = jsonConvert.convert<String>(json['clothing_size']);
+  if (clothingSize != null) {
+    tHEmployeeDetailEntity.clothingSize = clothingSize;
+  }
+  final THEmployeeDetailReviews? reviews = jsonConvert.convert<THEmployeeDetailReviews>(json['reviews']);
+  if (reviews != null) {
+    tHEmployeeDetailEntity.reviews = reviews;
+  }
+  return tHEmployeeDetailEntity;
+}
+
+Map<String, dynamic> $THEmployeeDetailEntityToJson(THEmployeeDetailEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['member_id'] = entity.memberId;
+  data['staff_id'] = entity.staffId;
+  data['staff'] = entity.staff?.toJson();
+  data['worker_name'] = entity.workerName;
+  data['mobile'] = entity.mobile;
+  data['icon'] = entity.icon;
+  data['sex'] = entity.sex;
+  data['nric'] = entity.nric;
+  data['hourly_rate'] = entity.hourlyRate;
+  data['clothing_size'] = entity.clothingSize;
+  data['reviews'] = entity.reviews?.toJson();
+  return data;
+}
+
+extension THEmployeeDetailEntityExtension on THEmployeeDetailEntity {
+  THEmployeeDetailEntity copyWith({
+    String? memberId,
+    String? staffId,
+    THEmployeeDetailStaff? staff,
+    String? workerName,
+    String? mobile,
+    String? icon,
+    String? sex,
+    String? nric,
+    String? hourlyRate,
+    String? clothingSize,
+    THEmployeeDetailReviews? reviews,
+  }) {
+    return THEmployeeDetailEntity()
+      ..memberId = memberId ?? this.memberId
+      ..staffId = staffId ?? this.staffId
+      ..staff = staff ?? this.staff
+      ..workerName = workerName ?? this.workerName
+      ..mobile = mobile ?? this.mobile
+      ..icon = icon ?? this.icon
+      ..sex = sex ?? this.sex
+      ..nric = nric ?? this.nric
+      ..hourlyRate = hourlyRate ?? this.hourlyRate
+      ..clothingSize = clothingSize ?? this.clothingSize
+      ..reviews = reviews ?? this.reviews;
+  }
+}
+
+THEmployeeDetailStaff $THEmployeeDetailStaffFromJson(Map<String, dynamic> json) {
+  final THEmployeeDetailStaff tHEmployeeDetailStaff = THEmployeeDetailStaff();
+  final String? id = jsonConvert.convert<String>(json['id']);
+  if (id != null) {
+    tHEmployeeDetailStaff.id = id;
+  }
+  final String? name = jsonConvert.convert<String>(json['name']);
+  if (name != null) {
+    tHEmployeeDetailStaff.name = name;
+  }
+  final String? sex = jsonConvert.convert<String>(json['sex']);
+  if (sex != null) {
+    tHEmployeeDetailStaff.sex = sex;
+  }
+  final String? mobile = jsonConvert.convert<String>(json['mobile']);
+  if (mobile != null) {
+    tHEmployeeDetailStaff.mobile = mobile;
+  }
+  final String? nric = jsonConvert.convert<String>(json['nric']);
+  if (nric != null) {
+    tHEmployeeDetailStaff.nric = nric;
+  }
+  final String? profilePicture = jsonConvert.convert<String>(json['profile_picture']);
+  if (profilePicture != null) {
+    tHEmployeeDetailStaff.profilePicture = profilePicture;
+  }
+  final String? visitorKey = jsonConvert.convert<String>(json['visitor_key']);
+  if (visitorKey != null) {
+    tHEmployeeDetailStaff.visitorKey = visitorKey;
+  }
+  final String? yyMemberId = jsonConvert.convert<String>(json['yy_member_id']);
+  if (yyMemberId != null) {
+    tHEmployeeDetailStaff.yyMemberId = yyMemberId;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    tHEmployeeDetailStaff.createdAt = createdAt;
+  }
+  final String? updatedAt = jsonConvert.convert<String>(json['updated_at']);
+  if (updatedAt != null) {
+    tHEmployeeDetailStaff.updatedAt = updatedAt;
+  }
+  final String? password = jsonConvert.convert<String>(json['password']);
+  if (password != null) {
+    tHEmployeeDetailStaff.password = password;
+  }
+  final String? defaultStaff = jsonConvert.convert<String>(json['default_staff']);
+  if (defaultStaff != null) {
+    tHEmployeeDetailStaff.defaultStaff = defaultStaff;
+  }
+  final String? typhoidDate = jsonConvert.convert<String>(json['typhoid_date']);
+  if (typhoidDate != null) {
+    tHEmployeeDetailStaff.typhoidDate = typhoidDate;
+  }
+  final String? typhoidFile = jsonConvert.convert<String>(json['typhoid_file']);
+  if (typhoidFile != null) {
+    tHEmployeeDetailStaff.typhoidFile = typhoidFile;
+  }
+  final String? foodHygiene = jsonConvert.convert<String>(json['food_hygiene']);
+  if (foodHygiene != null) {
+    tHEmployeeDetailStaff.foodHygiene = foodHygiene;
+  }
+  final String? criminalFile = jsonConvert.convert<String>(json['criminal_file']);
+  if (criminalFile != null) {
+    tHEmployeeDetailStaff.criminalFile = criminalFile;
+  }
+  final String? criminalDate = jsonConvert.convert<String>(json['criminal_date']);
+  if (criminalDate != null) {
+    tHEmployeeDetailStaff.criminalDate = criminalDate;
+  }
+  final String? email = jsonConvert.convert<String>(json['email']);
+  if (email != null) {
+    tHEmployeeDetailStaff.email = email;
+  }
+  final String? ownStaffId = jsonConvert.convert<String>(json['own_staff_id']);
+  if (ownStaffId != null) {
+    tHEmployeeDetailStaff.ownStaffId = ownStaffId;
+  }
+  final String? clothingSize = jsonConvert.convert<String>(json['clothing_size']);
+  if (clothingSize != null) {
+    tHEmployeeDetailStaff.clothingSize = clothingSize;
+  }
+  return tHEmployeeDetailStaff;
+}
+
+Map<String, dynamic> $THEmployeeDetailStaffToJson(THEmployeeDetailStaff entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['id'] = entity.id;
+  data['name'] = entity.name;
+  data['sex'] = entity.sex;
+  data['mobile'] = entity.mobile;
+  data['nric'] = entity.nric;
+  data['profile_picture'] = entity.profilePicture;
+  data['visitor_key'] = entity.visitorKey;
+  data['yy_member_id'] = entity.yyMemberId;
+  data['created_at'] = entity.createdAt;
+  data['updated_at'] = entity.updatedAt;
+  data['password'] = entity.password;
+  data['default_staff'] = entity.defaultStaff;
+  data['typhoid_date'] = entity.typhoidDate;
+  data['typhoid_file'] = entity.typhoidFile;
+  data['food_hygiene'] = entity.foodHygiene;
+  data['criminal_file'] = entity.criminalFile;
+  data['criminal_date'] = entity.criminalDate;
+  data['email'] = entity.email;
+  data['own_staff_id'] = entity.ownStaffId;
+  data['clothing_size'] = entity.clothingSize;
+  return data;
+}
+
+extension THEmployeeDetailStaffExtension on THEmployeeDetailStaff {
+  THEmployeeDetailStaff copyWith({
+    String? id,
+    String? name,
+    String? sex,
+    String? mobile,
+    String? nric,
+    String? profilePicture,
+    String? visitorKey,
+    String? yyMemberId,
+    String? createdAt,
+    String? updatedAt,
+    String? password,
+    String? defaultStaff,
+    String? typhoidDate,
+    String? typhoidFile,
+    String? foodHygiene,
+    String? criminalFile,
+    String? criminalDate,
+    String? email,
+    String? ownStaffId,
+    String? clothingSize,
+  }) {
+    return THEmployeeDetailStaff()
+      ..id = id ?? this.id
+      ..name = name ?? this.name
+      ..sex = sex ?? this.sex
+      ..mobile = mobile ?? this.mobile
+      ..nric = nric ?? this.nric
+      ..profilePicture = profilePicture ?? this.profilePicture
+      ..visitorKey = visitorKey ?? this.visitorKey
+      ..yyMemberId = yyMemberId ?? this.yyMemberId
+      ..createdAt = createdAt ?? this.createdAt
+      ..updatedAt = updatedAt ?? this.updatedAt
+      ..password = password ?? this.password
+      ..defaultStaff = defaultStaff ?? this.defaultStaff
+      ..typhoidDate = typhoidDate ?? this.typhoidDate
+      ..typhoidFile = typhoidFile ?? this.typhoidFile
+      ..foodHygiene = foodHygiene ?? this.foodHygiene
+      ..criminalFile = criminalFile ?? this.criminalFile
+      ..criminalDate = criminalDate ?? this.criminalDate
+      ..email = email ?? this.email
+      ..ownStaffId = ownStaffId ?? this.ownStaffId
+      ..clothingSize = clothingSize ?? this.clothingSize;
+  }
+}
+
+THEmployeeDetailReviews $THEmployeeDetailReviewsFromJson(Map<String, dynamic> json) {
+  final THEmployeeDetailReviews tHEmployeeDetailReviews = THEmployeeDetailReviews();
+  final String? count = jsonConvert.convert<String>(json['count']);
+  if (count != null) {
+    tHEmployeeDetailReviews.count = count;
+  }
+  final String? avgScore = jsonConvert.convert<String>(json['avg_score']);
+  if (avgScore != null) {
+    tHEmployeeDetailReviews.avgScore = avgScore;
+  }
+  return tHEmployeeDetailReviews;
+}
+
+Map<String, dynamic> $THEmployeeDetailReviewsToJson(THEmployeeDetailReviews entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['count'] = entity.count;
+  data['avg_score'] = entity.avgScore;
+  return data;
+}
+
+extension THEmployeeDetailReviewsExtension on THEmployeeDetailReviews {
+  THEmployeeDetailReviews copyWith({
+    String? count,
+    String? avgScore,
+  }) {
+    return THEmployeeDetailReviews()
+      ..count = count ?? this.count
+      ..avgScore = avgScore ?? this.avgScore;
+  }
+}

+ 121 - 0
packages/cs_domain/lib/generated/json/t_h_employee_remarks_entity.g.dart

@@ -0,0 +1,121 @@
+import 'package:domain/generated/json/base/json_convert_content.dart';
+import 'package:domain/entity/response/t_h_employee_remarks_entity.dart';
+
+THEmployeeRemarksEntity $THEmployeeRemarksEntityFromJson(Map<String, dynamic> json) {
+  final THEmployeeRemarksEntity tHEmployeeRemarksEntity = THEmployeeRemarksEntity();
+  final int? count = jsonConvert.convert<int>(json['count']);
+  if (count != null) {
+    tHEmployeeRemarksEntity.count = count;
+  }
+  final String? avgScore = jsonConvert.convert<String>(json['avg_score']);
+  if (avgScore != null) {
+    tHEmployeeRemarksEntity.avgScore = avgScore;
+  }
+  final List<THEmployeeRemarksReviews>? reviews = (json['reviews'] as List<dynamic>?)?.map(
+          (e) => jsonConvert.convert<THEmployeeRemarksReviews>(e) as THEmployeeRemarksReviews).toList();
+  if (reviews != null) {
+    tHEmployeeRemarksEntity.reviews = reviews;
+  }
+  final int? memberId = jsonConvert.convert<int>(json['member_id']);
+  if (memberId != null) {
+    tHEmployeeRemarksEntity.memberId = memberId;
+  }
+  final String? labourerName = jsonConvert.convert<String>(json['labourer_name']);
+  if (labourerName != null) {
+    tHEmployeeRemarksEntity.labourerName = labourerName;
+  }
+  return tHEmployeeRemarksEntity;
+}
+
+Map<String, dynamic> $THEmployeeRemarksEntityToJson(THEmployeeRemarksEntity entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['count'] = entity.count;
+  data['avg_score'] = entity.avgScore;
+  data['reviews'] = entity.reviews.map((v) => v.toJson()).toList();
+  data['member_id'] = entity.memberId;
+  data['labourer_name'] = entity.labourerName;
+  return data;
+}
+
+extension THEmployeeRemarksEntityExtension on THEmployeeRemarksEntity {
+  THEmployeeRemarksEntity copyWith({
+    int? count,
+    String? avgScore,
+    List<THEmployeeRemarksReviews>? reviews,
+    int? memberId,
+    String? labourerName,
+  }) {
+    return THEmployeeRemarksEntity()
+      ..count = count ?? this.count
+      ..avgScore = avgScore ?? this.avgScore
+      ..reviews = reviews ?? this.reviews
+      ..memberId = memberId ?? this.memberId
+      ..labourerName = labourerName ?? this.labourerName;
+  }
+}
+
+THEmployeeRemarksReviews $THEmployeeRemarksReviewsFromJson(Map<String, dynamic> json) {
+  final THEmployeeRemarksReviews tHEmployeeRemarksReviews = THEmployeeRemarksReviews();
+  final String? employerName = jsonConvert.convert<String>(json['employer_name']);
+  if (employerName != null) {
+    tHEmployeeRemarksReviews.employerName = employerName;
+  }
+  final double? attitudeRate = jsonConvert.convert<double>(json['attitude_rate']);
+  if (attitudeRate != null) {
+    tHEmployeeRemarksReviews.attitudeRate = attitudeRate;
+  }
+  final double? groomingRate = jsonConvert.convert<double>(json['grooming_rate']);
+  if (groomingRate != null) {
+    tHEmployeeRemarksReviews.groomingRate = groomingRate;
+  }
+  final double? performanceRate = jsonConvert.convert<double>(json['performance_rate']);
+  if (performanceRate != null) {
+    tHEmployeeRemarksReviews.performanceRate = performanceRate;
+  }
+  final double? experienceRate = jsonConvert.convert<double>(json['experience_rate']);
+  if (experienceRate != null) {
+    tHEmployeeRemarksReviews.experienceRate = experienceRate;
+  }
+  final String? feedback = jsonConvert.convert<String>(json['feedback']);
+  if (feedback != null) {
+    tHEmployeeRemarksReviews.feedback = feedback;
+  }
+  final String? createdAt = jsonConvert.convert<String>(json['created_at']);
+  if (createdAt != null) {
+    tHEmployeeRemarksReviews.createdAt = createdAt;
+  }
+  return tHEmployeeRemarksReviews;
+}
+
+Map<String, dynamic> $THEmployeeRemarksReviewsToJson(THEmployeeRemarksReviews entity) {
+  final Map<String, dynamic> data = <String, dynamic>{};
+  data['employer_name'] = entity.employerName;
+  data['attitude_rate'] = entity.attitudeRate;
+  data['grooming_rate'] = entity.groomingRate;
+  data['performance_rate'] = entity.performanceRate;
+  data['experience_rate'] = entity.experienceRate;
+  data['feedback'] = entity.feedback;
+  data['created_at'] = entity.createdAt;
+  return data;
+}
+
+extension THEmployeeRemarksReviewsExtension on THEmployeeRemarksReviews {
+  THEmployeeRemarksReviews copyWith({
+    String? employerName,
+    double? attitudeRate,
+    double? groomingRate,
+    double? performanceRate,
+    double? experienceRate,
+    String? feedback,
+    String? createdAt,
+  }) {
+    return THEmployeeRemarksReviews()
+      ..employerName = employerName ?? this.employerName
+      ..attitudeRate = attitudeRate ?? this.attitudeRate
+      ..groomingRate = groomingRate ?? this.groomingRate
+      ..performanceRate = performanceRate ?? this.performanceRate
+      ..experienceRate = experienceRate ?? this.experienceRate
+      ..feedback = feedback ?? this.feedback
+      ..createdAt = createdAt ?? this.createdAt;
+  }
+}

+ 490 - 0
packages/cs_domain/lib/repository/th_er_repository.dart

@@ -1,9 +1,14 @@
 import 'package:domain/entity/response/hotel_info_entity.dart';
+import 'package:domain/entity/response/job_list_add_staff_entity.dart';
 import 'package:domain/entity/response/job_list_e_r_detail_entity.dart';
 import 'package:domain/entity/response/job_list_e_r_option_entity.dart';
 import 'package:domain/entity/response/labour_request_e_r_entity.dart';
 import 'package:domain/entity/response/sign_in_sign_out_entity.dart';
 import 'package:domain/entity/response/switch_project_entity.dart';
+import 'package:domain/entity/response/t_h_applied_edit_entity.dart';
+import 'package:domain/entity/response/t_h_applied_employee_entity.dart';
+import 'package:domain/entity/response/t_h_applied_index_entity.dart';
+import 'package:domain/entity/response/t_h_applied_table_entity.dart';
 import 'package:get/get.dart';
 import 'package:plugin_platform/http/http_provider.dart';
 import 'package:plugin_platform/http/http_result.dart';
@@ -11,8 +16,15 @@ import 'package:plugin_platform/platform_export.dart';
 import 'package:shared/utils/util.dart';
 
 import '../constants/api_constants.dart';
+import '../entity/response/job_list_applied_work_flow_entity.dart';
+import '../entity/response/job_list_remark_view_entity.dart';
 import '../entity/response/labour_list_e_r_entity.dart';
 import '../entity/response/labour_request_e_r_option_entity.dart';
+import '../entity/response/staff_detail_entity.dart';
+import '../entity/response/staff_labour_history_entity.dart';
+import '../entity/response/staff_remark_history_entity.dart';
+import '../entity/response/t_h_employee_detail_entity.dart';
+import '../entity/response/t_h_employee_remarks_entity.dart';
 
 /// 泰国的 ER 的数据仓库
 class THERRepository extends GetxService {
@@ -312,4 +324,482 @@ class THERRepository extends GetxService {
     return result.convert();
   }
 
+  /// 获取 ER 工作 Applied 选项
+  Future<HttpResult<THAppliedIndexEntity>> fetchERAppliedOption({
+    required String? jobId,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["job_id"] = jobId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedOptionTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THAppliedIndexEntity.fromJson(json!);
+      return result.convert<THAppliedIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 获取 ER 工作 Applied Table
+  Future<HttpResult<THAppliedTableEntity>> fetchERAppliedTable({
+    required String? jobId,
+    required int curPage,
+    String? keyword,
+    String? status,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["job_id"] = jobId ?? "";
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = '10';
+    if (!Utils.isEmpty(keyword)) {
+      params["keyword"] = keyword!;
+    }
+    if (!Utils.isEmpty(status)) {
+      params["status"] = status!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedListTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THAppliedTableEntity.fromJson(json!);
+      return result.convert<THAppliedTableEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  // 刷新 Table
+  Future<HttpResult<THAppliedTableEntity>> 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.apiERAppliedListTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THAppliedTableEntity.fromJson(json!);
+      return result.convert<THAppliedTableEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// Applied 批量员工批准
+  Future<HttpResult> submitBatchStaffApprove(String? separatedIds, {required CancelToken cancelToken}) async {
+    Map<String, String> params = {};
+    params["applied_ids"] = separatedIds ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      method: HttpMethod.POST,
+      ApiConstants.apiERAppliedApproveTH,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// Applied 批量员工编辑
+  Future<HttpResult> batchEditStaffCheckTime(String? separatedIds, String? startDate, String? endDate, {required CancelToken cancelToken}) async {
+    Map<String, String> params = {};
+    params["applied_ids"] = separatedIds ?? "";
+    if (!Utils.isEmpty(startDate)) {
+      params["start_time"] = startDate!;
+    }
+    if (!Utils.isEmpty(endDate)) {
+      params["end_time"] = endDate!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      method: HttpMethod.POST,
+      ApiConstants.apiERAppliedEditTH,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 获取 ER 工作 Applied 编辑详情
+  Future<HttpResult<THAppliedEditEntity>> fetchERAppliedEditDetail({
+    required String? appliedId,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["applied_id"] = appliedId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedEditAttTH,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THAppliedEditEntity.fromJson(json!);
+      return result.convert<THAppliedEditEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// Applied 修改员工考勤提交
+  Future<HttpResult> editAppliedDetailSubmit({
+    required String? appliedId,
+    String? startTime,
+    String? endTime,
+    String? securityIn,
+    String? securityOut,
+    String? workIn,
+    String? workOut,
+    String? subtractHours,
+    String? status,
+    String? reasonType,
+    String? remark,
+    CancelToken? cancelToken,
+  }) async {
+    Map<String, String> params = {};
+    params["applied_id"] = appliedId ?? "";
+    if (!Utils.isEmpty(startTime)) {
+      params["start_time"] = startTime!;
+    }
+    if (!Utils.isEmpty(endTime)) {
+      params["end_time"] = endTime!;
+    }
+    if (!Utils.isEmpty(securityIn)) {
+      params["security_in"] = securityIn!;
+    }
+    if (!Utils.isEmpty(securityOut)) {
+      params["security_out"] = securityOut!;
+    }
+    if (!Utils.isEmpty(workIn)) {
+      params["work_in"] = workIn!;
+    }
+    if (!Utils.isEmpty(workOut)) {
+      params["work_out"] = workOut!;
+    }
+    if (!Utils.isEmpty(subtractHours)) {
+      params["subtract_hours"] = subtractHours!;
+    }
+    if (!Utils.isEmpty(status)) {
+      params["status"] = status!;
+    }
+    if (!Utils.isEmpty(reasonType)) {
+      params["reason_type"] = reasonType!;
+    }
+    if (!Utils.isEmpty(remark)) {
+      params["remark"] = remark!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      method: HttpMethod.POST,
+      ApiConstants.apiERAppliedEditAttSubmitTH,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 添加员工的全部员工数据列表
+  Future<HttpResult<THAppliedEmployeeEntity>> searchStaffList(
+    String? jobId,
+    String? keyword, {
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "10";
+
+    if (Utils.isNotEmpty(jobId)) {
+      params["job_id"] = jobId!;
+    }
+    if (Utils.isNotEmpty(keyword)) {
+      params["keyword"] = keyword!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedAddEmployeeTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THAppliedEmployeeEntity.fromJson(json!);
+      return result.convert<THAppliedEmployeeEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 添加员工到工作
+  Future<HttpResult<JobListAddStaffEntity>> 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.apiERAppliedAddEmployeeSubmitTH,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = JobListAddStaffEntity.fromJson(json!);
+      return result.convert<JobListAddStaffEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  // 员工的信息
+  Future<HttpResult<THEmployeeDetailEntity>> fetchStaffDetail(
+    String? memberId, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(memberId)) {
+      params["member_id"] = memberId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiEREmployeeInfoTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = THEmployeeDetailEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<THEmployeeDetailEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  // 员工的历史申请记录
+  Future<HttpResult<StaffLabourHistoryEntity>> fetchStaffLabourHistory(
+    String? memberId,
+    String? keyword, {
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "10";
+
+    if (!Utils.isEmpty(memberId)) {
+      params["member_id"] = memberId!;
+    }
+
+    if (!Utils.isEmpty(keyword)) {
+      params["keyword"] = keyword!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiEREmployeeHistoryTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = StaffLabourHistoryEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<StaffLabourHistoryEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  // 员工的历史评价记录
+  Future<HttpResult<THEmployeeRemarksEntity>> fetchStaffRemarkHistory(
+    String? memberId, {
+    required int curPage,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params["cur_page"] = curPage.toString();
+    params["page_size"] = "10";
+
+    if (!Utils.isEmpty(memberId)) {
+      params["member_id"] = memberId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiEREmployeeEvaluationTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = THEmployeeRemarksEntity.fromJson(json!);
+      return result.convert<THEmployeeRemarksEntity>(data: data);
+    }
+    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.apiERAppliedStaffReviewIndexTH,
+      isShowLoadingDialog: true,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      final json = result.getDataJson();
+      var data = JobListRemarkViewEntity.fromJson(json!);
+      return result.convert<JobListRemarkViewEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 单独给单个员工评分的提交
+  Future<HttpResult> remarkAppliedSingleStaffSubmit(
+    String? appliedId,
+    String? attitudeRate,
+    String? groomingRate,
+    String? performanceRate,
+    String? experienceRate,
+    String? content, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, dynamic> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+    if (!Utils.isEmpty(attitudeRate)) {
+      params["attitude_rate"] = (double.parse(attitudeRate!)).toInt();
+    }
+    if (!Utils.isEmpty(groomingRate)) {
+      params["grooming_rate"] = (double.parse(groomingRate!)).toInt();
+    }
+    if (!Utils.isEmpty(performanceRate)) {
+      params["performance_rate"] = (double.parse(performanceRate!)).toInt();
+    }
+    if (!Utils.isEmpty(experienceRate)) {
+      params["experience_rate"] = (double.parse(experienceRate!)).toInt();
+    }
+    if (!Utils.isEmpty(content)) {
+      params["feedback"] = content!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedStaffReviewSubmitTH,
+      isShowLoadingDialog: true,
+      method: HttpMethod.POST,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  // 员工状态的工作流
+  Future<HttpResult<JobListAppliedWorkFlowEntity>> fetchAppliedWorkFlow(
+      String? appliedId, {
+        CancelToken? cancelToken,
+      }) async {
+    //参数
+    Map<String, String> params = {};
+    if (!Utils.isEmpty(appliedId)) {
+      params["applied_id"] = appliedId!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiERAppliedStaffStateWorkflowTH,
+      params: params,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobListAppliedWorkFlowEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobListAppliedWorkFlowEntity>(data: data);
+    }
+    return result.convert();
+  }
+
 }

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

@@ -301,6 +301,10 @@ const Map<String, String> en_US = {
   'Retake': 'Retake',
   'thailand': 'Thailand',
   'Pre Selected': 'Pre Selected',
+  'Clothing Size': 'Clothing Size',
+  'ID Card No.': 'ID Card No.',
+  'Select All': 'Select All',
+  'Employer': 'Employer',
 
   //插件的国际化
   'Pull to refresh': 'Pull to refresh',

+ 4 - 0
packages/cs_resources/lib/local/language/zh_CN.dart

@@ -301,6 +301,10 @@ const Map<String, String> zh_CN = {
   'Retake': '重新获取',
   'thailand': '泰国',
   'Pre Selected': '预选',
+  'Clothing Size': '服装尺寸',
+  'ID Card No.': '身份证号码',
+  'Select All': '选择全部',
+  'Employer': '雇主',
 
   //插件的国际化
   'Pull to refresh': '下拉刷新',

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

@@ -152,6 +152,11 @@ class RouterPath {
   static const THLabourRequestER = '/th/labour/request/er';  //泰国的用工请求 ER
   static const THLabourRequestERAdd = '/th/labour/request/er/add';  //泰国的用工请求添加 ER
   static const THJobListER = '/th/job/list/er';  //泰国的用工请求添加 ER
+  static const THJobAppliedER = '/th/job/applied/er';  //泰国的已申请列表
+  static const THJobAppliedEditER = '/th/job/applied/edit/er';  //泰国的已申请列表修改员工考勤信息
+  static const THJobAppliedEmployeeER = '/th/job/applied/employee/er';  //泰国的已申请列表员工详情信息
+  static const THJobAppliedEmployeeRemarkER = '/th/job/applied/employee/remark/er';  //泰国的已申请列表员工的评价列表
+  static const THJobAppliedStaffWorkflow = '/th/job/applied/employee/workflow/er';  //泰国的已申请列表员工的评价列表
 
   //Runalone
   static const runAloneMain = '/runalone/main'; //独立运行的入口页面