浏览代码

越南的模板页面与功能

liukai 6 月之前
父节点
当前提交
7e3207eca1
共有 26 个文件被更改,包括 1270 次插入42 次删除
  1. 1 1
      packages/cpt_auth/lib/modules/main/main_controller.dart
  2. 115 0
      packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_controller.dart
  3. 302 0
      packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_page.dart
  4. 44 0
      packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_state.dart
  5. 7 0
      packages/cpt_labour/lib/modules/labour_template_list/add_edit_template.dart
  6. 175 0
      packages/cpt_labour/lib/modules/labour_template_list/labour_template_item.dart
  7. 215 0
      packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_controller.dart
  8. 155 0
      packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_page.dart
  9. 13 0
      packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_state.dart
  10. 10 2
      packages/cpt_labour/lib/router/labour_service_impl.dart
  11. 13 2
      packages/cpt_labour/lib/router/page_router.dart
  12. 1 1
      packages/cpt_labour_sg/lib/modules/job_template_add/job_template_add_page.dart
  13. 0 2
      packages/cpt_labour_sg/lib/modules/job_template_list/job_template_list_controller.dart
  14. 3 3
      packages/cpt_report/lib/modules/report_labour_vn/report_labour_vn_item.dart
  15. 7 5
      packages/cs_domain/lib/entity/response/job_template_edit_index_entity.dart
  16. 3 1
      packages/cs_domain/lib/entity/response/job_template_s_g_entity.dart
  17. 6 1
      packages/cs_domain/lib/generated/json/base/json_convert_content.dart
  18. 7 0
      packages/cs_domain/lib/generated/json/job_template_edit_index_entity.g.dart
  19. 15 8
      packages/cs_domain/lib/generated/json/job_template_s_g_entity.g.dart
  20. 153 0
      packages/cs_domain/lib/repository/labour_repository.dart
  21. 12 12
      packages/cs_domain/lib/repository/labour_sg_repository.dart
  22. 5 3
      packages/cs_resources/lib/local/language/en_US.dart
  23. 2 0
      packages/cs_resources/lib/local/language/vi_VN.dart
  24. 2 0
      packages/cs_resources/lib/local/language/zh_CN.dart
  25. 2 1
      packages/cs_router/lib/componentRouter/labour_service.dart
  26. 2 0
      packages/cs_router/lib/path/router_path.dart

+ 1 - 1
packages/cpt_auth/lib/modules/main/main_controller.dart

@@ -152,7 +152,7 @@ class MainController extends GetxController {
         break;
       case 'template':
         //越南的用工请求
-        ToastEngine.show("进入 Default Job Title 模块");
+        ComponentRouterServices.labourService.startLabourTemplatePage();
         break;
       case 'jobTitle':
         //新加坡的用工请求

+ 115 - 0
packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_controller.dart

@@ -0,0 +1,115 @@
+import 'package:domain/entity/response/job_template_edit_index_entity.dart';
+import 'package:domain/repository/labour_repository.dart';
+import 'package:get/get.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/log_utils.dart';
+import 'package:shared/utils/util.dart';
+
+import 'labour_template_add_state.dart';
+
+class LabourTemplateAddController extends GetxController with DioCancelableMixin {
+  final LabourRepository _labourRepository = Get.find();
+  final LabourTemplateAddState state = LabourTemplateAddState();
+
+  // 获取添加或者编辑的详情
+  void _fetchAddEditIndexDetail() async {
+    //获取到数据
+    Future<HttpResult<JobTemplateEditIndexEntity>> taskFuture;
+    if (Utils.isNotEmpty(state.templateId) && state.templateId != "0") {
+      //编辑
+      taskFuture = _labourRepository.fetchJobTemplateEditIndex(state.templateId, cancelToken: cancelToken);
+    } else {
+      //新增
+      taskFuture = _labourRepository.fetchJobTemplateAddIndex(cancelToken: cancelToken);
+    }
+
+    var result = await taskFuture;
+
+    //处理数据
+    if (result.isSuccess) {
+      state.indexEntity = result.data;
+
+      var templateNameController = state.formData['template_name']!['controller'];
+      var descController = state.formData['desc']!['controller'];
+      var noteController = state.formData['note']!['controller'];
+      templateNameController.text = state.indexEntity?.jobTitle ?? "";
+      descController.text = state.indexEntity?.description ?? "";
+      noteController.text = state.indexEntity?.note ?? "";
+
+      //默认赋值
+      state.selectedAgeList = state.indexEntity?.ageList.where((e) => e.checked == "checked").map((e) => e.value!).toList() ?? [];
+      Log.d("当前选中的年龄1:${ state.selectedAgeList}");
+      state.selectedLanguageList = state.indexEntity?.languageList.where((e) => e.checked == "checked").map((e) => e.value!).toList() ?? [];
+      Log.d("当前选中的语言1:${ state.selectedLanguageList}");
+      state.gender = state.indexEntity?.sexList.firstWhere((e) => e.checked == "checked").value;
+
+      update();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  /// 提交
+  void doSubmit() async {
+    var templateNameController = state.formData['template_name']!['controller'];
+    var descController = state.formData['desc']!['controller'];
+    var noteController = state.formData['note']!['controller'];
+
+    String templateName = templateNameController.text.toString();
+    String desc = descController.text.toString();
+    String note = noteController.text.toString();
+
+    //只校验模版的名称
+    if (Utils.isEmpty(templateName)) {
+      ToastEngine.show("Enter Job Template Name".tr);
+      return;
+    }
+
+    Future<HttpResult> taskFuture;
+    if (Utils.isNotEmpty(state.templateId) && state.templateId != "0") {
+      taskFuture = _labourRepository.editLabourTemplateSubmit(
+        state.templateId,
+        templateName,
+        desc,
+        note,
+        state.selectedAgeList.join(","),
+        state.gender,
+        state.selectedLanguageList.join(","),
+        cancelToken: cancelToken,
+      );
+    } else {
+      taskFuture = _labourRepository.addLabourTemplateSubmit(
+        templateName,
+        desc,
+        note,
+        state.selectedAgeList.join(","),
+        state.gender,
+        state.selectedLanguageList.join(","),
+        cancelToken: cancelToken,
+      );
+    }
+
+    var result = await taskFuture;
+
+    //处理数据
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      //根据类型刷新
+      state.cb?.call(state.templateId);
+
+      Get.back();
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    _fetchAddEditIndexDetail();
+  }
+}

+ 302 - 0
packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_page.dart

@@ -0,0 +1,302 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:shared/utils/screen_util.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/no_shadow_scroll_behavior.dart';
+import 'package:widgets/shatter/custom_check_box.dart';
+import 'package:widgets/shatter/custom_radio_check.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/round_my_text_field.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'labour_template_add_controller.dart';
+
+import 'package:plugin_basic/base/base_stateless_page.dart';
+import 'package:plugin_basic/utils/ext_get_nav.dart';
+import 'package:router/path/router_path.dart';
+
+import 'labour_template_add_state.dart';
+
+/*
+ * 模板的添加与编辑
+ */
+class LabourTemplateAddPage extends BaseStatelessPage<LabourTemplateAddController> {
+  LabourTemplateAddPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance(
+    String templateId,
+    void Function(dynamic value)? cb,
+  ) {
+    return Get.start(RouterPath.labourTemplateAdd, arguments: {'templateId': templateId, 'cb': cb});
+  }
+
+  late LabourTemplateAddState state;
+
+  @override
+  void initState() {
+    state = controller.state;
+    state.templateId = Get.arguments['templateId'];
+    state.cb = Get.arguments['cb'] as void Function(dynamic)?;
+  }
+
+  @override
+  LabourTemplateAddController createRawController() {
+    return LabourTemplateAddController();
+  }
+
+  @override
+  Widget buildWidget(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return Scaffold(
+        extendBodyBehindAppBar: true,
+        appBar: MyAppBar.appBar(context, Utils.isEmpty(state.templateId) ? "Create Template".tr : "Edit Template".tr),
+        body: SafeArea(
+          bottom: true,
+          top: false,
+          child: Container(
+            width: double.infinity,
+            height: double.infinity,
+            padding: EdgeInsets.only(top: kToolbarHeight + ScreenUtil.getStatusBarH(context) + 1),
+            decoration: const BoxDecoration(
+              gradient: LinearGradient(
+                colors: [
+                  Color(0xFF091D44),
+                  Color(0xFF245A8A),
+                  Color(0xFF7F7CEC),
+                ],
+                begin: Alignment.topCenter,
+                end: Alignment.bottomCenter,
+              ),
+            ),
+            child: Scrollbar(
+              child: ScrollConfiguration(
+                behavior: NoShadowScrollBehavior(),
+                child: SingleChildScrollView(
+                  scrollDirection: Axis.vertical,
+                  physics: const BouncingScrollPhysics(),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      //模板名称
+                      FormRequireText(text: "Template Name".tr).marginOnly(left: 15, top: 19),
+
+                      CustomTextField(
+                        formKey: "template_name",
+                        formData: state.formData,
+                        height: 46,
+                        fontSize: 14,
+                        onSubmit: (key, value) {
+                          state.formData[key]!['focusNode'].unfocus();
+                          FocusScope.of(context).requestFocus(state.formData['desc']!['focusNode']);
+                        },
+                        marginTop: 10,
+                      ),
+
+                      //年龄
+                      MyTextView(
+                        "Age".tr,
+                        textColor: Colors.white,
+                        fontSize: 14,
+                        isFontRegular: true,
+                        marginLeft: 15,
+                        marginTop: 15,
+                      ),
+
+                      // 年龄的多选
+                      CustomCheckBox(
+                        options: state.indexEntity?.ageList.map((e) => e.txt!).toList() ?? [],
+                        onOptionsSelected: (selected) {
+                          // 转换选中的索引为对应的 value
+                          state.selectedAgeList = selected
+                              .map((index) {
+                                return state.indexEntity?.ageList[index].value; // 获取对应的 value
+                              })
+                              .whereType<String>()
+                              .toList();
+                        },
+                        selectedOptions: state.indexEntity?.ageList.where((e) => e.checked == "checked").map((e) => e.txt!).toList() ?? [],
+                      ).marginOnly(left: 15, right: 15, top: 10),
+
+                      //性别
+                      MyTextView(
+                        "Gender".tr,
+                        textColor: Colors.white,
+                        fontSize: 14,
+                        isFontRegular: true,
+                        marginLeft: 15,
+                        marginTop: 15,
+                      ),
+
+                      //性别单选
+                      CustomRadioCheck(
+                        options: state.indexEntity?.sexList.map((e) => e.txt!).toList() ?? [],
+                        onOptionSelected: (index, text) {
+                          state.gender = state.indexEntity!.sexList[index].value;
+                        },
+                        selectedPosition: state.indexEntity?.sexList.indexWhere((e) => e.checked == "checked") ?? -1,
+                      ).marginOnly(left: 15, right: 15, top: 10),
+
+                      //语言
+                      MyTextView(
+                        "Language".tr,
+                        textColor: Colors.white,
+                        fontSize: 14,
+                        isFontRegular: true,
+                        marginLeft: 15,
+                        marginTop: 15,
+                      ),
+
+                      // 语言的多选
+                      CustomCheckBox(
+                        options: state.indexEntity?.languageList.map((e) => e.txt!).toList() ?? [],
+                        onOptionsSelected: (selected) {
+                          // 转换选中的索引为对应的 value
+                          state.selectedLanguageList = selected
+                              .map((index) {
+                                return state.indexEntity?.languageList[index].value; // 获取对应的 value
+                              })
+                              .whereType<String>()
+                              .toList();
+                        },
+                        selectedOptions: state.indexEntity?.languageList.where((e) => e.checked == "checked").map((e) => e.txt!).toList() ?? [],
+                      ).marginOnly(left: 15, right: 15, top: 10),
+
+
+                      //模板详情
+                      MyTextView(
+                        "Description".tr,
+                        textColor: Colors.white,
+                        fontSize: 14,
+                        isFontRegular: true,
+                        marginLeft: 15,
+                        marginTop: 15,
+                      ),
+
+                      IgnoreKeyboardDismiss(
+                        child: Container(
+                          height: 130,
+                          margin: const EdgeInsets.only(left: 15, right: 15, top: 10),
+                          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,
+                            enabled: true,
+                            focusNode: state.formData["desc"]!['focusNode'],
+                            controller: state.formData["desc"]!['controller'],
+                            // 装饰
+                            decoration: InputDecoration(
+                              isDense: true,
+                              isCollapsed: true,
+                              border: InputBorder.none,
+                              hintText: state.formData["desc"]!['hintText'],
+                              hintStyle: const TextStyle(
+                                color: ColorConstants.textGrayAECAE5,
+                                fontSize: 15.0,
+                                fontWeight: FontWeight.w400,
+                              ),
+                            ),
+                            style: const TextStyle(
+                              color: ColorConstants.white,
+                              fontSize: 15.0,
+                              fontWeight: FontWeight.w400,
+                            ),
+                            // 键盘动作右下角图标
+                            textInputAction: TextInputAction.next,
+                            onSubmitted: (value) {
+                              state.formData[key]!['focusNode'].unfocus();
+                              FocusScope.of(context).requestFocus(state.formData['contact']!['focusNode']);
+                            },
+                          ),
+                        ),
+                      ),
+
+                      //备注
+                      MyTextView(
+                        "Note".tr,
+                        textColor: Colors.white,
+                        fontSize: 14,
+                        isFontRegular: true,
+                        marginLeft: 15,
+                        marginTop: 18,
+                      ),
+
+                      IgnoreKeyboardDismiss(
+                        child: Container(
+                          height: 130,
+                          margin: const EdgeInsets.only(left: 15, right: 15, top: 10),
+                          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,
+                            enabled: true,
+                            focusNode: state.formData["note"]!['focusNode'],
+                            controller: state.formData["note"]!['controller'],
+                            // 装饰
+                            decoration: InputDecoration(
+                              isDense: true,
+                              isCollapsed: true,
+                              border: InputBorder.none,
+                              hintText: state.formData["note"]!['hintText'],
+                              hintStyle: const TextStyle(
+                                color: ColorConstants.textGrayAECAE5,
+                                fontSize: 14.0,
+                                fontWeight: FontWeight.w400,
+                              ),
+                            ),
+                            style: const TextStyle(
+                              color: ColorConstants.white,
+                              fontSize: 14.0,
+                              fontWeight: FontWeight.w400,
+                            ),
+                            // 键盘动作右下角图标
+                            textInputAction: TextInputAction.next,
+                            onSubmitted: (value) {
+                              state.formData[key]!['focusNode'].unfocus();
+                              FocusScope.of(context).requestFocus(state.formData['contact']!['focusNode']);
+                            },
+                          ),
+                        ),
+                      ),
+
+                      //提交按钮
+                      MyButton(
+                        type: ClickType.throttle,
+                        milliseconds: 500,
+                        onPressed: () {
+                          FocusScope.of(context).unfocus();
+                          controller.doSubmit();
+                        },
+                        text: "Submit".tr,
+                        textColor: ColorConstants.white,
+                        fontSize: 16,
+                        radius: 20,
+                        backgroundColor: ColorConstants.textYellowFFBB1B,
+                        fontWeight: FontWeight.w500,
+                      ).marginSymmetric(vertical: 25, horizontal: 15),
+                    ],
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+}

+ 44 - 0
packages/cpt_labour/lib/modules/labour_template_add/labour_template_add_state.dart

@@ -0,0 +1,44 @@
+import 'package:domain/entity/response/job_template_edit_index_entity.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_basic/basic_export.dart';
+
+class LabourTemplateAddState {
+  //表单的校验与数据
+  Map<String, Map<String, dynamic>> formData = {
+    'template_name': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter...'.tr,
+      'obsecure': false,
+    },
+    'desc': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter...'.tr,
+      'obsecure': false,
+    },
+    'note': {
+      'value': '',
+      'controller': TextEditingController(),
+      'focusNode': FocusNode(),
+      'hintText': 'Enter...'.tr,
+      'obsecure': false,
+    },
+  };
+
+
+  final foodHygieneCertOption = ["Yes".tr, "No".tr];
+
+  String templateId = "";
+  void Function(dynamic value)? cb;
+
+  JobTemplateEditIndexEntity? indexEntity;  //新增或者编辑的详情
+
+
+  List<String> selectedAgeList = [];   //选中的 age 的 id
+  List<String> selectedLanguageList = [];   //选中的 language 的 id
+  String? gender;
+
+}

+ 7 - 0
packages/cpt_labour/lib/modules/labour_template_list/add_edit_template.dart

@@ -0,0 +1,7 @@
+//编辑和新增页面返回的对象
+class AddEditTemplate{
+   bool isEdit = false;
+   String? templateId;
+
+   AddEditTemplate(this.isEdit, this.templateId);
+}

+ 175 - 0
packages/cpt_labour/lib/modules/labour_template_list/labour_template_item.dart

@@ -0,0 +1,175 @@
+import 'package:cs_resources/constants/color_constants.dart';
+import 'package:domain/entity/response/job_template_s_g_entity.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:plugin_basic/basic_export.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_view.dart';
+
+/*
+ * 用工请求的主页面列表Item
+ */
+class LabourTemplateItem extends StatelessWidget {
+  final int index;
+  final JobTemplateSGRows item;
+  final VoidCallback? onDeleteAction;
+  final VoidCallback? onEditAction;
+
+  LabourTemplateItem({
+    required this.index,
+    required this.item,
+    this.onDeleteAction,
+    this.onEditAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      padding: const EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      decoration: BoxDecoration(
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        borderRadius: BorderRadius.circular(5), // 设置圆角
+      ),
+      child: Column(
+        mainAxisSize: MainAxisSize.max,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          // 标题
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Template Name".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+              MyTextView(
+                item.name ?? "-",
+                marginLeft: 5,
+                isFontMedium: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ),
+
+          // 创建人
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Created By".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+              MyTextView(
+                item.createdBy ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 14),
+
+          // 创建时间
+          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: 14),
+
+          // 更新时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Updated At".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+              MyTextView(
+                item.updatedAt ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 14),
+
+          //按钮组
+          Visibility(
+            visible: item.actionList.isNotEmpty,
+            child: Row(
+              mainAxisSize: MainAxisSize.max,
+              mainAxisAlignment: MainAxisAlignment.end,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                //编辑按钮
+                Visibility(
+                  visible: item.actionList.contains("edit"),
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onEditAction?.call();
+                    },
+                    text: "Edit".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: ColorConstants.textGreen0AC074,
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
+                //删除按钮
+                Visibility(
+                  visible: item.actionList.contains("delete"),
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onDeleteAction?.call();
+                    },
+                    text: "Delete".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: ColorConstants.textRedFF6262,
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+              ],
+            ).marginOnly(top: 18, bottom: 2),
+
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 215 - 0
packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_controller.dart

@@ -0,0 +1,215 @@
+import 'package:domain/entity/response/job_template_s_g_entity.dart';
+import 'package:domain/repository/labour_sg_repository.dart';
+import 'package:get/get.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/notify/notify_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
+import 'package:widgets/dialog/app_default_dialog.dart';
+import 'package:widgets/load_state_layout.dart';
+import 'package:widgets/widget_export.dart';
+
+import '../labour_template_add/labour_template_add_page.dart';
+import 'labour_template_list_state.dart';
+
+class LabourTemplateListController extends GetxController with DioCancelableMixin {
+  final LabourSGRepository _labourRepository = Get.find();
+  final LabourTemplateListState state = LabourTemplateListState();
+
+  var _curPage = 1;
+  var _needShowPlaceholder = true;
+
+  //页面PlaceHolder的展示
+  LoadState loadingState = LoadState.State_Success;
+  String? errorMessage;
+
+  //刷新页面状态
+  void changeLoadingState(LoadState state) {
+    loadingState = state;
+    update();
+  }
+
+  // Refresh 控制器
+  final EasyRefreshController refreshController = EasyRefreshController(
+    controlFinishRefresh: true,
+    controlFinishLoad: true,
+  );
+
+  // Refresh 刷新事件
+  Future onRefresh() async {
+    _curPage = 1;
+    fetchNotifyList();
+  }
+
+  // Refresh 加载事件
+  Future loadMore() async {
+    _curPage++;
+    fetchNotifyList();
+  }
+
+  // 重试请求
+  Future retryRequest() async {
+    _curPage = 1;
+    _needShowPlaceholder = true;
+    fetchNotifyList();
+  }
+
+  /// 获取服务器数据,通知消息列表
+  Future fetchNotifyList() async {
+    if (_needShowPlaceholder) {
+      changeLoadingState(LoadState.State_Loading);
+    }
+
+    var listResult = await _labourRepository.fetchJobTemplateList(state.keyword, curPage: _curPage, cancelToken: cancelToken);
+
+    // 处理数据
+    if (listResult.isSuccess) {
+      handleList(listResult.data?.rows);
+    } else {
+      errorMessage = listResult.errorMsg;
+      changeLoadingState(LoadState.State_Error);
+    }
+
+    // 最后赋值
+    _needShowPlaceholder = false;
+  }
+
+  // 处理数据与展示的逻辑
+  void handleList(List<JobTemplateSGRows>? list) {
+    if (list != null && list.isNotEmpty) {
+      //有数据,判断是刷新还是加载更多的数据
+      if (_curPage == 1) {
+        //刷新的方式
+        state.datas.clear();
+        state.datas.addAll(list);
+        refreshController.finishRefresh();
+
+        //更新展示的状态
+        changeLoadingState(LoadState.State_Success);
+      } else {
+        //加载更多
+        state.datas.addAll(list);
+        refreshController.finishLoad();
+        update();
+      }
+    } else {
+      if (_curPage == 1) {
+        //展示无数据的布局
+        state.datas.clear();
+        changeLoadingState(LoadState.State_Empty);
+        refreshController.finishRefresh();
+      } else {
+        //展示加载完成,没有更多数据了
+        refreshController.finishLoad(IndicatorResult.noMore);
+      }
+    }
+  }
+
+  // 执行搜索
+  void doSearch(String keyword) {
+    state.keyword = keyword;
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  // 清空搜索条件
+  void resetFiltering() {
+    state.keyword = "";
+    state.searchController.text = "";
+
+    //赋值之后刷新
+    refreshController.callRefresh();
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    fetchNotifyList();
+  }
+
+  @override
+  void onClose() {
+    state.datas.clear();
+    super.onClose();
+  }
+
+  //去添加模板的页面
+  void gotoTemplateAddPage() {
+    LabourTemplateAddPage.startInstance("", (result) {
+      if (result is String) {
+        refreshController.callRefresh();
+      }
+    });
+  }
+
+  //去编辑的页面
+  void gotoEditPage(String templateId) {
+    LabourTemplateAddPage.startInstance(templateId, (result) {
+      if (result is String) {
+        fetchItemByIdAndRefreshItem(templateId);
+      }
+    });
+  }
+
+  //删除工作模板
+  void deleteJobTitle(int index) {
+    DialogEngine.show(
+        widget: AppDefaultDialog(
+      title: "Confirmation".tr,
+      message: "Are you sure you want to delete this job template?".tr,
+      confirmAction: () {
+        _requestDeactivate(index);
+      },
+    ));
+  }
+
+  // 请求接口删除JobTitle
+  void _requestDeactivate(int index) async {
+    final item = state.datas[index];
+    var result = await _labourRepository.deleteJobTemplateSubmit(item.id.toString(), cancelToken: cancelToken);
+
+    if (result.isSuccess) {
+      NotifyEngine.showSuccess("Successful".tr);
+
+      if (state.datas.length <= 1) {
+        refreshController.callRefresh();
+      } else {
+        state.datas.removeAt(index);
+        update();
+      }
+    } else {
+      ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
+    }
+  }
+
+  /// 根据ID获取Item对象,用于刷新
+  void fetchItemByIdAndRefreshItem(String ids) async {
+    var result = await _labourRepository.fetchJobTemplateListByIds(
+      ids,
+      cancelToken: cancelToken,
+    );
+
+    //处理数据
+    if (result.isSuccess) {
+      var data = result.data;
+      if (data != null && data.rows.isNotEmpty) {
+        List<JobTemplateSGRows> newItem = data.rows;
+
+        // 创建一个 Map 来加速查找
+        Map<int, JobTemplateSGRows> 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);
+    }
+  }
+}

+ 155 - 0
packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_page.dart

@@ -0,0 +1,155 @@
+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_button.dart';
+import 'package:widgets/widget_export.dart';
+
+import 'labour_template_item.dart';
+import '../labour_template_list/labour_template_list_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 '../labour_template_list/labour_template_list_state.dart';
+
+/// 新加坡的模板列表页面
+class LabourTemplateListPage extends BaseStatefulPage<LabourTemplateListController> {
+  LabourTemplateListPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance() {
+    return Get.start(RouterPath.labourTemplateList);
+  }
+
+  @override
+  LabourTemplateListController createRawController() {
+    return LabourTemplateListController();
+  }
+
+  @override
+  State<LabourTemplateListPage> createState() => _LabourTemplateListState();
+
+}
+
+class _LabourTemplateListState extends BaseState<LabourTemplateListPage, LabourTemplateListController> {
+
+  late LabourTemplateListState state;
+
+  @override
+  void initState() {
+    super.initState();
+    state = controller.state;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return autoCtlGetBuilder(builder: (controller) {
+      return SafeArea(
+        bottom: true,
+        top: false,
+        child: Container(
+          width: double.infinity,
+          height: double.infinity,
+          padding: EdgeInsets.only(top: ScreenUtil.getStatusBarH(context)),
+          decoration: const BoxDecoration(
+            gradient: LinearGradient(
+              colors: [
+                Color(0xFF091D44),
+                Color(0xFF245A8A),
+                Color(0xFF7F7CEC),
+              ],
+              begin: Alignment.topCenter,
+              end: Alignment.bottomCenter,
+            ),
+          ),
+          child: Column(
+            children: [
+              MyAppBar.searchTitleBar(
+                context,
+                value: state.keyword,
+                hintText: 'Template Name'.tr,
+                controller: state.searchController,
+                onSearch: (keyword) {
+                  controller.doSearch(keyword);
+                },
+                actions: [
+                  //重置按钮
+                  MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      controller.resetFiltering();
+                    },
+                    text: "Reset".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor("#2BA9F9", opacity: 0.5),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(right: 15),
+                ],
+              ),
+
+              Row(
+                children: [
+                  MyButton(
+                    type: ClickType.throttle,
+                    milliseconds: 500,
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      controller.gotoTemplateAddPage();
+                    },
+                    text: "Add New".tr,
+                    textColor: ColorConstants.white,
+                    fontSize: 16,
+                    radius: 20,
+                    backgroundColor: hexToColor("#FFBB1B"),
+                    fontWeight: FontWeight.w500,
+                  ).expanded(),
+                ],
+              ).marginOnly(left: 15,right: 15,top: 15,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 LabourTemplateItem(
+                              index: index,
+                              item: state.datas[index],
+                              onEditAction: () {
+                                controller.gotoEditPage(state.datas[index].id.toString());
+                              },
+                              onDeleteAction: () {
+                                controller.deleteJobTitle(index);
+                              },
+                            );
+                          },
+                          childCount: state.datas.length,
+                        ))
+                  ],
+                ),
+              ).expanded(),
+            ],
+          ),
+        ),
+      );
+    });
+  }
+}
+

+ 13 - 0
packages/cpt_labour/lib/modules/labour_template_list/labour_template_list_state.dart

@@ -0,0 +1,13 @@
+import 'package:domain/entity/response/job_template_s_g_entity.dart';
+import 'package:flutter/material.dart';
+
+class LabourTemplateListState {
+
+  //筛选条件
+  final TextEditingController searchController = TextEditingController();
+  String keyword = "";
+
+  //页面的列表数据
+  List<JobTemplateSGRows> datas = [];
+
+}

+ 10 - 2
packages/cpt_labour/lib/router/labour_service_impl.dart

@@ -3,6 +3,7 @@ import 'package:router/componentRouter/labour_service.dart';
 import 'package:shared/utils/log_utils.dart';
 
 import '../modules/labour_request_list/labour_request_list_page.dart';
+import '../modules/labour_template_list/labour_template_list_page.dart';
 
 class LabourServiceImpl extends GetxService implements LabourService {
 
@@ -12,16 +13,23 @@ class LabourServiceImpl extends GetxService implements LabourService {
   }
 
   @override
+  void startLabourTemplatePage() {
+    LabourTemplateListPage.startInstance();
+  }
+
+  @override
   void onInit() {
     super.onInit();
     //初始化资源
-    Log.d("ProfileServiceImpl 初始化资源");
+    Log.d("LabourServiceImpl 初始化资源");
   }
 
   @override
   void onClose() {
     super.onClose();
     //销毁资源
-    Log.d("ProfileServiceImpl 销毁资源");
+    Log.d("LabourServiceImpl 销毁资源");
   }
+
+
 }

+ 13 - 2
packages/cpt_labour/lib/router/page_router.dart

@@ -1,11 +1,11 @@
 
-import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:router/path/router_path.dart';
-
 import '../modules/labour_request_add/labour_request_add_page.dart';
 import '../modules/labour_request_list/labour_request_list_page.dart';
 import '../modules/labour_request_workflow/labour_request_workflow_page.dart';
+import '../modules/labour_template_add/labour_template_add_page.dart';
+import '../modules/labour_template_list/labour_template_list_page.dart';
 
 class LabourPageRouter {
 
@@ -29,5 +29,16 @@ class LabourPageRouter {
       page: () => LabourRequestWorkflowPage(),
     ),
 
+    //用工请求状态修改工作流
+    GetPage(
+      name: RouterPath.labourTemplateList,
+      page: () => LabourTemplateListPage(),
+    ),
+
+    //用工请求状态修改工作流
+    GetPage(
+      name: RouterPath.labourTemplateAdd,
+      page: () => LabourTemplateAddPage(),
+    ),
   ];
 }

+ 1 - 1
packages/cpt_labour_sg/lib/modules/job_template_add/job_template_add_page.dart

@@ -358,7 +358,7 @@ class JobTemplateAddPage extends BaseStatelessPage<JobTemplateAddController> {
                   ),
                 ),
               ),
-            ).expanded(),
+            ),
           ),
         ),
       );

+ 0 - 2
packages/cpt_labour_sg/lib/modules/job_template_list/job_template_list_controller.dart

@@ -5,8 +5,6 @@ import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
 import 'package:plugin_platform/engine/notify/notify_engine.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
-import 'package:shared/utils/log_utils.dart';
-import 'package:shared/utils/util.dart';
 import 'package:widgets/dialog/app_default_dialog.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';

+ 3 - 3
packages/cpt_report/lib/modules/report_labour_vn/report_labour_vn_item.dart

@@ -22,7 +22,7 @@ class ReportLabourVNItem extends StatelessWidget {
   Widget build(BuildContext context) {
     return Container(
       width: double.infinity,
-      padding: const EdgeInsets.only(top: 16, bottom: 20),
+      padding: const EdgeInsets.only(top: 16, bottom: 20,left: 15,right: 15),
       margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
       decoration: BoxDecoration(
         color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
@@ -40,7 +40,7 @@ class ReportLabourVNItem extends StatelessWidget {
             fontSize: 14,
             isFontBold: true,
             marginBottom: 15,
-            marginLeft: 20,
+            marginLeft: 5,
             marginRight: 20,
             textColor: type == 0
                 ? ColorConstants.textGreen0AC074
@@ -210,7 +210,7 @@ class ReportLabourVNItem extends StatelessWidget {
                   ],
                 ).constrained(maxWidth: 100).marginOnly(left: 25),
               ],
-            ).marginOnly(left: 20, right: 20, top: 18, bottom: 2),
+            ).marginOnly(left: 5, right: 5, top: 18, bottom: 2),
           ),
         ],
       ),

+ 7 - 5
packages/cs_domain/lib/entity/response/job_template_edit_index_entity.dart

@@ -7,12 +7,14 @@ export 'package:domain/generated/json/job_template_edit_index_entity.g.dart';
 class JobTemplateEditIndexEntity {
 	@JSONField(name: "template_id")
 	int templateId = 0;
-	String? name = null;
-	String? contact = null;
+	String? name;  //新加坡用这个为标题
+	@JSONField(name: "job_title")
+	String? jobTitle;  //越南用这个为标题
+	String? contact;
 	@JSONField(name: "contact_no")
-	String? contactNo = null;
-	String? description = null;
-	String? note = null;
+	String? contactNo;
+	String? description;
+	String? note;
 	@JSONField(name: "with_food_cert")
 	int withFoodCert = 0;
 	@JSONField(name: "age_list")

+ 3 - 1
packages/cs_domain/lib/entity/response/job_template_s_g_entity.dart

@@ -25,15 +25,17 @@ class JobTemplateSGRows {
 	int id = 0;
 	String? name = null;
 	String? contact = null;
+	@JSONField(name: "created_by")
+	String? createdBy = null;
 	@JSONField(name: "contact_no")
 	String? contactNo = null;
-	String? note = null;
 	@JSONField(name: "created_at")
 	String? createdAt = null;
 	@JSONField(name: "updated_at")
 	String? updatedAt = null;
 	@JSONField(name: "action_list")
 	List<String> actionList = [];
+	String? note = null;
 
 	JobTemplateSGRows();
 

+ 6 - 1
packages/cs_domain/lib/generated/json/base/json_convert_content.dart

@@ -171,7 +171,12 @@ class JsonConvert {
         if (value == null) {
           return null;
         }
-        return convertFuncMap[type]!(value as Map<String, dynamic>) as T;
+        var covertFunc = convertFuncMap[type]!;
+        if (covertFunc is Map<String, dynamic>) {
+          return covertFunc(value as Map<String, dynamic>) as T;
+        } else {
+          return covertFunc(Map<String, dynamic>.from(value)) as T;
+        }
       } else {
         throw UnimplementedError('$type unimplemented,you can try running the app again');
       }

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

@@ -11,6 +11,10 @@ JobTemplateEditIndexEntity $JobTemplateEditIndexEntityFromJson(Map<String, dynam
   if (name != null) {
     jobTemplateEditIndexEntity.name = name;
   }
+  final String? jobTitle = jsonConvert.convert<String>(json['job_title']);
+  if (jobTitle != null) {
+    jobTemplateEditIndexEntity.jobTitle = jobTitle;
+  }
   final String? contact = jsonConvert.convert<String>(json['contact']);
   if (contact != null) {
     jobTemplateEditIndexEntity.contact = contact;
@@ -53,6 +57,7 @@ Map<String, dynamic> $JobTemplateEditIndexEntityToJson(JobTemplateEditIndexEntit
   final Map<String, dynamic> data = <String, dynamic>{};
   data['template_id'] = entity.templateId;
   data['name'] = entity.name;
+  data['job_title'] = entity.jobTitle;
   data['contact'] = entity.contact;
   data['contact_no'] = entity.contactNo;
   data['description'] = entity.description;
@@ -68,6 +73,7 @@ extension JobTemplateEditIndexEntityExtension on JobTemplateEditIndexEntity {
   JobTemplateEditIndexEntity copyWith({
     int? templateId,
     String? name,
+    String? jobTitle,
     String? contact,
     String? contactNo,
     String? description,
@@ -80,6 +86,7 @@ extension JobTemplateEditIndexEntityExtension on JobTemplateEditIndexEntity {
     return JobTemplateEditIndexEntity()
       ..templateId = templateId ?? this.templateId
       ..name = name ?? this.name
+      ..jobTitle = jobTitle ?? this.jobTitle
       ..contact = contact ?? this.contact
       ..contactNo = contactNo ?? this.contactNo
       ..description = description ?? this.description

+ 15 - 8
packages/cs_domain/lib/generated/json/job_template_s_g_entity.g.dart

@@ -47,14 +47,14 @@ JobTemplateSGRows $JobTemplateSGRowsFromJson(Map<String, dynamic> json) {
   if (contact != null) {
     jobTemplateSGRows.contact = contact;
   }
+  final String? createdBy = jsonConvert.convert<String>(json['created_by']);
+  if (createdBy != null) {
+    jobTemplateSGRows.createdBy = createdBy;
+  }
   final String? contactNo = jsonConvert.convert<String>(json['contact_no']);
   if (contactNo != null) {
     jobTemplateSGRows.contactNo = contactNo;
   }
-  final String? note = jsonConvert.convert<String>(json['note']);
-  if (note != null) {
-    jobTemplateSGRows.note = note;
-  }
   final String? createdAt = jsonConvert.convert<String>(json['created_at']);
   if (createdAt != null) {
     jobTemplateSGRows.createdAt = createdAt;
@@ -68,6 +68,10 @@ JobTemplateSGRows $JobTemplateSGRowsFromJson(Map<String, dynamic> json) {
   if (actionList != null) {
     jobTemplateSGRows.actionList = actionList;
   }
+  final String? note = jsonConvert.convert<String>(json['note']);
+  if (note != null) {
+    jobTemplateSGRows.note = note;
+  }
   return jobTemplateSGRows;
 }
 
@@ -76,11 +80,12 @@ Map<String, dynamic> $JobTemplateSGRowsToJson(JobTemplateSGRows entity) {
   data['id'] = entity.id;
   data['name'] = entity.name;
   data['contact'] = entity.contact;
+  data['created_by'] = entity.createdBy;
   data['contact_no'] = entity.contactNo;
-  data['note'] = entity.note;
   data['created_at'] = entity.createdAt;
   data['updated_at'] = entity.updatedAt;
   data['action_list'] = entity.actionList;
+  data['note'] = entity.note;
   return data;
 }
 
@@ -89,20 +94,22 @@ extension JobTemplateSGRowsExtension on JobTemplateSGRows {
     int? id,
     String? name,
     String? contact,
+    String? createdBy,
     String? contactNo,
-    String? note,
     String? createdAt,
     String? updatedAt,
     List<String>? actionList,
+    String? note,
   }) {
     return JobTemplateSGRows()
       ..id = id ?? this.id
       ..name = name ?? this.name
       ..contact = contact ?? this.contact
+      ..createdBy = createdBy ?? this.createdBy
       ..contactNo = contactNo ?? this.contactNo
-      ..note = note ?? this.note
       ..createdAt = createdAt ?? this.createdAt
       ..updatedAt = updatedAt ?? this.updatedAt
-      ..actionList = actionList ?? this.actionList;
+      ..actionList = actionList ?? this.actionList
+      ..note = note ?? this.note;
   }
 }

+ 153 - 0
packages/cs_domain/lib/repository/labour_repository.dart

@@ -9,6 +9,7 @@ import 'package:plugin_platform/http/http_result.dart';
 import 'package:shared/utils/util.dart';
 
 import '../constants/api_constants.dart';
+import '../entity/response/job_template_edit_index_entity.dart';
 
 /// 用工请求相关
 class LabourRepository extends GetxService {
@@ -307,4 +308,156 @@ class LabourRepository extends GetxService {
     }
     return result.convert();
   }
+
+  /// 添加工作模板的详情或选项数据
+  Future<HttpResult<JobTemplateEditIndexEntity>> fetchJobTemplateAddIndex({
+    CancelToken? cancelToken,
+  }) async {
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobTemplateAddIndexSG,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobTemplateEditIndexEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobTemplateEditIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 编辑工作模板的详情或选项数据
+  Future<HttpResult<JobTemplateEditIndexEntity>> fetchJobTemplateEditIndex(
+      String? templateId, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, String> params = {};
+    params["template_id"] = templateId ?? "";
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobTemplateEditIndexSG,
+      params: params,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = JobTemplateEditIndexEntity.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<JobTemplateEditIndexEntity>(data: data);
+    }
+    return result.convert();
+  }
+
+  /// 添加工作模板的提交
+  Future<HttpResult> addLabourTemplateSubmit(
+      String? name,
+      String? description,
+      String? note,
+      String? age,
+      String? sex,
+      String? language, {
+        CancelToken? cancelToken,
+      }) async {
+    //参数
+    Map<String, String> params = {};
+    params['job_title'] = name ?? "";
+
+    if (!Utils.isEmpty(description)) {
+      params["description"] = description!;
+    }
+
+    if (!Utils.isEmpty(note)) {
+      params["note"] = note!;
+    }
+
+    if (!Utils.isEmpty(age)) {
+      params["age"] = age!;
+    }
+
+    if (!Utils.isEmpty(sex)) {
+      params["gender"] = sex!;
+    }
+
+    if (!Utils.isEmpty(language)) {
+      params["language"] = language!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobTemplateAddSubmitSG,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
+  /// 编辑工作模板的提交
+  Future<HttpResult> editLabourTemplateSubmit(
+      String? templateId,
+      String? name,
+      String? description,
+      String? note,
+      String? age,
+      String? sex,
+      String? language, {
+        CancelToken? cancelToken,
+      }) async {
+    //参数
+    Map<String, String> params = {};
+    params['job_title'] = name ?? "";
+    params['template_id'] = templateId ?? "";
+
+    if (!Utils.isEmpty(description)) {
+      params["description"] = description!;
+    }
+
+    if (!Utils.isEmpty(note)) {
+      params["note"] = note!;
+    }
+
+    if (!Utils.isEmpty(age)) {
+      params["age"] = age!;
+    }
+
+    if (!Utils.isEmpty(sex)) {
+      params["gender"] = sex!;
+    }
+
+    if (!Utils.isEmpty(language)) {
+      params["language"] = language!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiJobTemplateEditSubmitSG,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
+
 }

+ 12 - 12
packages/cs_domain/lib/repository/labour_sg_repository.dart

@@ -352,12 +352,12 @@ class LabourSGRepository extends GetxService {
   Future<HttpResult> addJobTemplateSubmit(
     String? name,
     String? contact,
-    String? contact_no,
+    String? contactNo,
     String? description,
     String? note,
     String? age,
     String? sex,
-    String? with_food_cert,
+    String? withFoodCert,
     String? language, {
     CancelToken? cancelToken,
   }) async {
@@ -369,8 +369,8 @@ class LabourSGRepository extends GetxService {
       params["contact"] = contact!;
     }
 
-    if (!Utils.isEmpty(contact_no)) {
-      params["contact_no"] = contact_no!;
+    if (!Utils.isEmpty(contactNo)) {
+      params["contact_no"] = contactNo!;
     }
 
     if (!Utils.isEmpty(description)) {
@@ -389,8 +389,8 @@ class LabourSGRepository extends GetxService {
       params["sex"] = sex!;
     }
 
-    if (!Utils.isEmpty(with_food_cert)) {
-      params["with_food_cert"] = with_food_cert!;
+    if (!Utils.isEmpty(withFoodCert)) {
+      params["with_food_cert"] = withFoodCert!;
     }
 
     if (!Utils.isEmpty(language)) {
@@ -419,12 +419,12 @@ class LabourSGRepository extends GetxService {
     String? templateId,
     String? name,
     String? contact,
-    String? contact_no,
+    String? contactNo,
     String? description,
     String? note,
     String? age,
     String? sex,
-    String? with_food_cert,
+    String? withFoodCert,
     String? language, {
     CancelToken? cancelToken,
   }) async {
@@ -437,8 +437,8 @@ class LabourSGRepository extends GetxService {
       params["contact"] = contact!;
     }
 
-    if (!Utils.isEmpty(contact_no)) {
-      params["contact_no"] = contact_no!;
+    if (!Utils.isEmpty(contactNo)) {
+      params["contact_no"] = contactNo!;
     }
 
     if (!Utils.isEmpty(description)) {
@@ -457,8 +457,8 @@ class LabourSGRepository extends GetxService {
       params["sex"] = sex!;
     }
 
-    if (!Utils.isEmpty(with_food_cert)) {
-      params["with_food_cert"] = with_food_cert!;
+    if (!Utils.isEmpty(withFoodCert)) {
+      params["with_food_cert"] = withFoodCert!;
     }
 
     if (!Utils.isEmpty(language)) {

+ 5 - 3
packages/cs_resources/lib/local/language/en_US.dart

@@ -50,7 +50,7 @@ const Map<String, String> en_US = {
   'Notice': 'Notice',
   'Are you sure you need to exit the system?': 'Are you sure you need to exit the system?',
   'Are you sure you want to deactivate your account? You will not be able to login into the app once you proceed with the request.':
-  'Are you sure you want to deactivate your account? You will not be able to login into the app once you proceed with the request.',
+      'Are you sure you want to deactivate your account? You will not be able to login into the app once you proceed with the request.',
   'Welcome': 'Welcome',
   'Switch Projects': 'Switch Projects',
   'Account Deactivation': 'Account Deactivation',
@@ -234,7 +234,9 @@ const Map<String, String> en_US = {
   'TotalAmt': 'TotalAmt',
   'Hours': 'Hours',
   'Monthly Staff Request Report': 'Monthly Staff Request Report',
-  'Finance Report':'Finance Report',
+  'Finance Report': 'Finance Report',
+  'Created By': 'Created By',
+  'Language': 'Language',
 
   //插件的国际化
   'Pull to refresh': 'Pull to refresh',
@@ -252,4 +254,4 @@ const Map<String, String> en_US = {
   'Click again and exit the app': 'Click again and exit the app',
   'The login credential have expired, please log in again.': 'The login credentials have expired, please log in again.',
   'Successful': 'Successful',
-};
+};

+ 2 - 0
packages/cs_resources/lib/local/language/vi_VN.dart

@@ -235,6 +235,8 @@ const Map<String, String> vi_VN = {
   'Hours': 'Giờ',
   'Monthly Staff Request Report': 'Báo cáo nhu cầu nhân viên hàng tháng',
   'Finance Report':'Báo cáo tài chính',
+  'Created By': 'Trang chủ',
+  'Language': 'Ngôn ngữ',
 
   //插件的国际化
   "Pull to refresh": "Kéo để làm mới",

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

@@ -235,6 +235,8 @@ const Map<String, String> zh_CN = {
   'Hours': '小时',
   'Monthly Staff Request Report': '月度员工请求报表',
   'Finance Report': '财务报表',
+  'Created By': '创建者',
+  'Language': '语言',
 
   //插件的国际化
   'Pull to refresh': '下拉刷新',

+ 2 - 1
packages/cs_router/lib/componentRouter/labour_service.dart

@@ -1,9 +1,10 @@
 
-/**
+/*
  * Labour组件对应的路由抽象接口
  */
 abstract class LabourService {
 
   void startLabourRequestPage();
 
+  void startLabourTemplatePage();
 }

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

@@ -31,6 +31,8 @@ class RouterPath {
   static const jobLabourRequestAdd = '/labour/add'; //用工请求添加
   static const jobLabourRequestDetail = '/labour/detail'; //用工请求详情
   static const jobLabourRequestWorkflow = '/labour/workflow'; //用工请求修改状态的工作流
+  static const labourTemplateList = '/labour/template/list'; //模板列表
+  static const labourTemplateAdd = '/labour/template/add'; //模板添加
 
   //其他模块和报表模块
   static const deviceList = '/device/list'; //雇主绑定的设备列表