Bläddra i källkod

labour request 的列表,添加,更新,刷新, Copy

liukai 1 månad sedan
förälder
incheckning
87e9c688d5

+ 50 - 14
packages/cpt_uk/lib/modules/job/labour_request_add/labour_request_add_controller.dart

@@ -1,28 +1,33 @@
 import 'package:domain/entity/response/labour_request_edit_index_entity.dart';
 import 'package:domain/repository/labour_repository.dart';
+import 'package:domain/repository/uk_job_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/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/http_result.dart';
 import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/event_bus.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'package:shared/utils/util.dart';
 import 'package:widgets/picker/date_picker_util.dart';
 import 'package:widgets/picker/option_pick_util.dart';
 
+import '../../../widget/date_range_picker_dialog.dart';
 import 'labour_request_add_state.dart';
 
 class LabourRequestAddController extends GetxController {
   final LabourRepository _labourRepository = Get.find();
+  final UKJobRepository _ukJobRepository = Get.find();
   final LabourRequestAddState state = LabourRequestAddState();
 
   /// 获取首页的数据
   void fetchRequestDetail() async {
     //获取到数据
     Future<HttpResult<LabourRequestEditIndexEntity>> taskFuture;
-    if (state.pageType != 0 && Utils.isNotEmpty(state.appliedId) && state.appliedId != "0") {
+    if (Utils.isNotEmpty(state.appliedId) && state.appliedId != "0") {
       taskFuture = _labourRepository.fetchLabourRequestEditDetail(state.appliedId);
     } else {
       taskFuture = _labourRepository.fetchLabourRequestAddOption();
@@ -33,6 +38,7 @@ class LabourRequestAddController extends GetxController {
     //处理数据
     if (result.isSuccess) {
       state.labReqOption = result.data;
+      state.selectedDate = state.labReqOption?.jobStart == null ? null : DateTimeUtils.getDateTime(state.labReqOption!.jobStart!);
       state.selectedStartTime = state.labReqOption?.jobStart == null ? null : DateTimeUtils.getDateTime(state.labReqOption!.jobStart!);
       state.selectedEndTime = state.labReqOption?.jobEnd == null ? null : DateTimeUtils.getDateTime(state.labReqOption!.jobEnd!);
       state.noStaff = state.labReqOption?.needNum.toString() == "0" ? "" : state.labReqOption?.needNum.toString();
@@ -89,22 +95,24 @@ class LabourRequestAddController extends GetxController {
       taskFuture = _labourRepository.editLabourRequestSubmit(
         state.appliedId,
         state.selectedTemplateId,
-        DateTimeUtils.formatDate(state.selectedStartTime),
-        DateTimeUtils.formatDate(state.selectedEndTime),
+        "${DateTimeUtils.formatDate(state.selectedDate, format: 'yyyy-MM-dd')} ${DateTimeUtils.formatDate(state.selectedStartTime, format: 'HH:mm')}:00",
+        "${DateTimeUtils.formatDate(state.selectedDate, format: 'yyyy-MM-dd')} ${DateTimeUtils.formatDate(state.selectedEndTime, format: 'HH:mm')}:00",
         state.selectedDepartmentId,
         needNum,
-        state.chargeOptionId,
+        'hour',
         state.labReqOption?.serviceType == 1 ? amount : null,
       );
     } else {
-      taskFuture = _labourRepository.addLabourRequestSubmit(
-        state.selectedTemplateId,
-        DateTimeUtils.formatDate(state.selectedStartTime),
-        DateTimeUtils.formatDate(state.selectedEndTime),
-        state.selectedDepartmentId,
-        needNum,
-        state.chargeOptionId,
-        state.labReqOption?.serviceType == 1 ? amount : null,
+      taskFuture = _ukJobRepository.addLabourRequestSubmit(
+        templateId: state.selectedTemplateId,
+        jobDate: DateTimeUtils.formatDate(state.selectedDate, format: 'yyyy-MM-dd'),
+        startTime: DateTimeUtils.formatDate(state.selectedStartTime, format: 'HH:mm'),
+        endTime: DateTimeUtils.formatDate(state.selectedEndTime, format: 'HH:mm'),
+        departmentId: state.selectedDepartmentId,
+        needNum: needNum,
+        salaryBy: 'hour',
+        repeatDate: state.repeatDateStr,
+        amount: state.labReqOption?.serviceType == 1 ? amount : null,
       );
     }
 
@@ -156,6 +164,23 @@ class LabourRequestAddController extends GetxController {
     );
   }
 
+  //选择日期
+  void pickJobDate() {
+    if (state.labReqOption == null || state.pageType == 2) {
+      return;
+    }
+
+    DatePickerUtil.showCupertinoDatePicker(
+      selectedDateTime: state.selectedDate,
+      mode: CupertinoDatePickerMode.date,
+      onDateTimeChanged: (date) {
+        state.selectedDate = date;
+        update();
+      },
+      title: "Job Date".tr,
+    );
+  }
+
   //选择开始时间
   void pickStartTime() {
     if (state.labReqOption == null || state.pageType == 2) {
@@ -164,7 +189,7 @@ class LabourRequestAddController extends GetxController {
 
     DatePickerUtil.showCupertinoDatePicker(
       selectedDateTime: state.selectedStartTime,
-      mode: CupertinoDatePickerMode.dateAndTime,
+      mode: CupertinoDatePickerMode.time,
       onDateTimeChanged: (date) {
         state.selectedStartTime = date;
         update();
@@ -181,7 +206,7 @@ class LabourRequestAddController extends GetxController {
 
     DatePickerUtil.showCupertinoDatePicker(
       selectedDateTime: state.selectedEndTime ?? state.selectedStartTime,
-      mode: CupertinoDatePickerMode.dateAndTime,
+      mode: CupertinoDatePickerMode.time,
       onDateTimeChanged: (date) {
         state.selectedEndTime = date;
         update();
@@ -216,4 +241,15 @@ class LabourRequestAddController extends GetxController {
       },
     );
   }
+
+  //选择时间段
+  void pickDateRange() {
+    DialogEngine.show(widget: DateRangePickerDialog(
+      confirmAction: (dateStr) {
+        Log.d("选择的时间段:$dateStr");
+        state.repeatDateStr = dateStr;
+        update();
+      },
+    ));
+  }
 }

+ 149 - 56
packages/cpt_uk/lib/modules/job/labour_request_add/labour_request_add_page.dart

@@ -66,7 +66,7 @@ class _LabourRequestAddState extends BaseState<UKLabourRequestAddPage, LabourReq
                     ? "Edit Labour Requisition".tr
                     : "Labour Requisition".tr),
         body: SafeArea(
-        bottom: MediaQuery.of(context).padding.bottom > 38,
+          bottom: MediaQuery.of(context).padding.bottom > 38,
           top: false,
           child: Container(
             width: double.infinity,
@@ -140,7 +140,7 @@ class _LabourRequestAddState extends BaseState<UKLabourRequestAddPage, LabourReq
 
                       //开始时间
                       FormRequireText(
-                        text: "Start Time".tr,
+                        text: "Job Date".tr,
                       ).marginOnly(top: 15),
 
                       //选择时间
@@ -158,9 +158,9 @@ class _LabourRequestAddState extends BaseState<UKLabourRequestAddPage, LabourReq
                           mainAxisAlignment: MainAxisAlignment.start,
                           children: [
                             MyTextView(
-                              state.selectedStartTime == null ? "" : DateTimeUtils.formatDate(state.selectedStartTime),
+                              state.selectedDate == null ? "" : DateTimeUtils.formatDate(state.selectedDate, format: 'yyyy-MM-dd'),
                               fontSize: 14,
-                              hint: "Job Start Time".tr,
+                              hint: "Job Date".tr,
                               textHintColor: ColorConstants.textGrayAECAE5,
                               isFontMedium: true,
                               textColor: ColorConstants.white,
@@ -174,47 +174,90 @@ class _LabourRequestAddState extends BaseState<UKLabourRequestAddPage, LabourReq
                         ),
                       ).onTap(() {
                         FocusScope.of(context).unfocus();
-                        controller.pickStartTime();
+                        controller.pickJobDate();
                       }),
 
-                      //结束时间
-                      FormRequireText(
-                        text: "End Time".tr,
-                      ).marginOnly(top: 15),
+                      Row(
+                        children: [
+                          Container(
+                            padding: const EdgeInsets.only(left: 16, right: 10),
+                            margin: const EdgeInsets.only(top: 10),
+                            height: 45,
+                            decoration: BoxDecoration(
+                              color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                              borderRadius: const BorderRadius.all(Radius.circular(5)),
+                            ),
+                            child: Row(
+                              mainAxisSize: MainAxisSize.max,
+                              crossAxisAlignment: CrossAxisAlignment.center,
+                              mainAxisAlignment: MainAxisAlignment.start,
+                              children: [
+                                MyTextView(
+                                  state.selectedStartTime == null ? "" : DateTimeUtils.formatDate(state.selectedStartTime, format: 'HH:mm'),
+                                  fontSize: 14,
+                                  hint: "Job Start Time".tr,
+                                  textHintColor: ColorConstants.textGrayAECAE5,
+                                  isFontMedium: true,
+                                  textColor: ColorConstants.white,
+                                ).expanded(),
+                                //下拉选图标
+                                Visibility(
+                                  visible: state.pageType != 2,
+                                  child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                                ),
+                              ],
+                            ),
+                          ).onTap(() {
+                            FocusScope.of(context).unfocus();
+                            controller.pickStartTime();
+                          }).expanded(),
 
-                      //选择时间
-                      Container(
-                        padding: const EdgeInsets.only(left: 16, right: 10),
-                        margin: const EdgeInsets.only(top: 10),
-                        height: 45,
-                        decoration: BoxDecoration(
-                          color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
-                          borderRadius: const BorderRadius.all(Radius.circular(5)),
-                        ),
-                        child: Row(
-                          mainAxisSize: MainAxisSize.max,
-                          crossAxisAlignment: CrossAxisAlignment.center,
-                          mainAxisAlignment: MainAxisAlignment.start,
-                          children: [
-                            MyTextView(
-                              state.selectedEndTime == null ? "" : DateTimeUtils.formatDate(state.selectedEndTime),
-                              fontSize: 14,
-                              hint: "Job End Time".tr,
-                              textHintColor: ColorConstants.textGrayAECAE5,
-                              isFontMedium: true,
-                              textColor: ColorConstants.white,
-                            ).expanded(),
-                            //下拉选图标
-                            Visibility(
-                              visible: state.pageType != 2,
-                              child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                          //分割线
+                          MyTextView(
+                            "-",
+                            textColor: Colors.white,
+                            marginLeft: 10,
+                            marginRight: 10,
+                            fontSize: 14,
+                            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(state.pageType == 2 ? 0.5 : 0.2),
+                              borderRadius: const BorderRadius.all(Radius.circular(5)),
                             ),
-                          ],
-                        ),
-                      ).onTap(() {
-                        FocusScope.of(context).unfocus();
-                        controller.pickEndTime();
-                      }),
+                            child: Row(
+                              mainAxisSize: MainAxisSize.max,
+                              crossAxisAlignment: CrossAxisAlignment.center,
+                              mainAxisAlignment: MainAxisAlignment.start,
+                              children: [
+                                MyTextView(
+                                  state.selectedEndTime == null ? "" : DateTimeUtils.formatDate(state.selectedEndTime, format: 'HH:mm'),
+                                  fontSize: 14,
+                                  hint: "Job End Time".tr,
+                                  textHintColor: ColorConstants.textGrayAECAE5,
+                                  isFontMedium: true,
+                                  textColor: ColorConstants.white,
+                                ).expanded(),
+                                //下拉选图标
+                                Visibility(
+                                  visible: state.pageType != 2,
+                                  child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                                ),
+                              ],
+                            ),
+                          ).onTap(() {
+                            FocusScope.of(context).unfocus();
+                            controller.pickEndTime();
+                          }).expanded(),
+                        ],
+                      ),
+                      //选择时间
 
                       //工作选择部门
                       FormRequireText(
@@ -286,21 +329,71 @@ class _LabourRequestAddState extends BaseState<UKLabourRequestAddPage, LabourReq
                         marginTop: 10,
                       ),
 
-                      // FormRequireText(
-                      //   text: "Salary By".tr,
-                      // ).marginOnly(top: 15),
-                      //
-                      // //选择计费类型
-                      // state.labReqOption != null
-                      //     ? CustomRadioCheck(
-                      //   options: state.labReqOption!.chargeList.map((e) => e.txt).whereType<String>().toList(), //后台返回的数据展示,并且根据后台的数据匹配索引
-                      //   selectedPosition: state.labReqOption!.chargeList.indexWhere((element) => element.checked == "checked"),
-                      //   onOptionSelected: (index, text) {
-                      //     //修改内存的值
-                      //     state.chargeOptionId = state.labReqOption!.chargeList[index].value;
-                      //   },
-                      // ).marginOnly(top: 15)
-                      //     : CircularProgressIndicator(),
+                      //重复的日期
+                      Visibility(
+                        visible: state.pageType == 0,
+                        child: MyTextView(
+                          "Repeat Date".tr,
+                          fontSize: 15,
+                          textColor: Colors.white,
+                          isFontRegular: true,
+                          marginTop: 15,
+                        ),
+                      ),
+
+                      //重复的日期区间
+                      Visibility(
+                        visible: state.pageType == 0,
+                        child:  Container(
+                          padding: const EdgeInsets.only(left: 16, right: 10, top: 5, bottom: 5),
+                          margin: const EdgeInsets.only(top: 10),
+                          decoration: BoxDecoration(
+                            color: const Color(0xFF4DCFF6).withOpacity(state.pageType == 2 ? 0.5 : 0.2),
+                            borderRadius: const BorderRadius.all(Radius.circular(5)),
+                          ),
+                          child: Row(
+                            mainAxisSize: MainAxisSize.max,
+                            crossAxisAlignment: CrossAxisAlignment.center,
+                            mainAxisAlignment: MainAxisAlignment.start,
+                            children: [
+                              //横向的流式布局
+                              Expanded(
+                                child: Wrap(
+                                  spacing: 8.0, // 子组件之间的水平间距
+                                  runSpacing: 5.0, // 子组件之间的垂直间距
+                                  children: state.repeatDateStr == null
+                                      ? []
+                                      : List.generate(state.repeatDateStr!.split(",").length, (index) {
+                                    return MyTextView(
+                                      state.repeatDateStr!.split(",")[index],
+                                      textColor: Colors.white,
+                                      isFontRegular: true,
+                                      fontSize: 14,
+                                      backgroundColor: ColorConstants.string2Color('#0AC074'),
+                                      paddingTop: 5,
+                                      paddingBottom: 5,
+                                      paddingLeft: 7.5,
+                                      paddingRight: 7.5,
+                                      cornerRadius: 5.0,
+                                    );
+                                  }),
+                                ),
+                              ),
+
+                              const SizedBox(width: 10),
+
+                              //下拉选图标
+                              Visibility(
+                                visible: state.pageType != 2,
+                                child: const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                              ),
+                            ],
+                          ),
+                        ).constrained(minHeight: 60).onTap(() {
+                          FocusScope.of(context).unfocus();
+                          controller.pickDateRange();
+                        }),
+                      ),
 
                       //选择是否需要输入金额
                       Visibility(

+ 2 - 0
packages/cpt_uk/lib/modules/job/labour_request_add/labour_request_add_state.dart

@@ -11,8 +11,10 @@ class LabourRequestAddState {
   LabourRequestEditIndexEntity? labReqOption;
 
   //页面对应的选择的条件
+  DateTime? selectedDate;
   DateTime? selectedStartTime;
   DateTime? selectedEndTime;
+  String? repeatDateStr;  //2025-06-28,2025-06-29,2025-06-30
   String? selectedTemplateId;
   String? selectedDepartmentId;
   String? noStaff;  //成员数量

+ 22 - 22
packages/cpt_uk/lib/modules/job/labour_request_list/labour_request_filter.dart

@@ -67,9 +67,9 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
           height: kToolbarHeight + ScreenUtil.getStatusBarH(context) + 1,
         ),
         Container(
-          padding: EdgeInsets.only(left: 15, right: 15, top: 17.5, bottom: 20),
+          padding: const EdgeInsets.only(left: 15, right: 15, top: 17.5, bottom: 20),
           width: double.infinity,
-          decoration: BoxDecoration(
+          decoration: const BoxDecoration(
             color: Colors.white,
           ),
           child: Column(
@@ -85,12 +85,12 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
 
               //选择部门
               Container(
-                padding: EdgeInsets.only(left: 16, right: 10),
-                margin: EdgeInsets.only(top: 10),
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
                 height: 45,
-                decoration: BoxDecoration(
+                decoration: const BoxDecoration(
                   color: ColorConstants.grayECECEC,
-                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
                 ),
                 child: Row(
                   mainAxisSize: MainAxisSize.max,
@@ -107,7 +107,7 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
                       isFontMedium: true,
                       textColor: ColorConstants.black33,
                     ).expanded(),
-                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
                   ],
                 ),
               ).onTap(() {
@@ -125,12 +125,12 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
 
               //选择状态
               Container(
-                padding: EdgeInsets.only(left: 16, right: 10),
-                margin: EdgeInsets.only(top: 10),
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
                 height: 45,
-                decoration: BoxDecoration(
+                decoration: const BoxDecoration(
                   color: ColorConstants.grayECECEC,
-                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
                 ),
                 child: Row(
                   mainAxisSize: MainAxisSize.max,
@@ -147,7 +147,7 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
                       isFontMedium: true,
                       textColor: ColorConstants.black33,
                     ).expanded(),
-                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
                   ],
                 ),
               ).onTap(() {
@@ -165,12 +165,12 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
 
               //选择时间
               Container(
-                padding: EdgeInsets.only(left: 16, right: 10),
-                margin: EdgeInsets.only(top: 10),
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
                 height: 45,
-                decoration: BoxDecoration(
+                decoration: const BoxDecoration(
                   color: ColorConstants.grayECECEC,
-                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
                 ),
                 child: Row(
                   mainAxisSize: MainAxisSize.max,
@@ -185,7 +185,7 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
                       isFontMedium: true,
                       textColor: ColorConstants.black33,
                     ).expanded(),
-                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
                   ],
                 ),
               ).onTap(() {
@@ -203,12 +203,12 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
 
               //选择结束日期
               Container(
-                padding: EdgeInsets.only(left: 16, right: 10),
-                margin: EdgeInsets.only(top: 10),
+                padding: const EdgeInsets.only(left: 16, right: 10),
+                margin: const EdgeInsets.only(top: 10),
                 height: 45,
-                decoration: BoxDecoration(
+                decoration: const BoxDecoration(
                   color: ColorConstants.grayECECEC,
-                  borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
                 ),
                 child: Row(
                   mainAxisSize: MainAxisSize.max,
@@ -223,7 +223,7 @@ class _LabourRequestFilterState extends State<LabourRequestFilter> {
                       isFontMedium: true,
                       textColor: ColorConstants.black33,
                     ).expanded(),
-                    MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
+                    const MyAssetImage(Assets.baseServiceTriangleDropDownIcon, width: 11.5, height: 6.28),
                   ],
                 ),
               ).onTap(() {

+ 72 - 5
packages/cpt_uk/lib/modules/job/labour_request_list/labour_request_item.dart

@@ -18,6 +18,7 @@ class LabourRequestItem extends StatelessWidget {
   final VoidCallback? onRecallAction;
   final VoidCallback? onDetailAction;
   final VoidCallback? onEditAction;
+  final VoidCallback? onCopyAction;
 
   LabourRequestItem({
     required this.index,
@@ -26,15 +27,16 @@ class LabourRequestItem extends StatelessWidget {
     this.onRecallAction,
     this.onDetailAction,
     this.onEditAction,
+    this.onCopyAction,
   });
 
   @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),
+      padding: const EdgeInsets.symmetric(vertical: 23, horizontal: 21),
+      margin: const EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
       decoration: BoxDecoration(
-        color: Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
+        color: const Color(0xFF4DCFF6).withOpacity(0.2), // 设置背景颜色和不透明度
         borderRadius: BorderRadius.circular(5), // 设置圆角
       ),
       child: Column(
@@ -78,13 +80,36 @@ class LabourRequestItem extends StatelessWidget {
             ],
           ).marginOnly(top: 15),
 
-          // 工作日期时间
+          // 工作日期
           Row(
             mainAxisSize: MainAxisSize.max,
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
               MyTextView(
-                "Datetime:".tr,
+                "${"Job Date".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //日期时间
+              MyTextView(
+                item.jobDate ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
+          // 工作时间
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Job Time".tr}:",
                 isFontRegular: true,
                 textColor: ColorConstants.textGrayAECAE5,
                 fontSize: 14,
@@ -124,6 +149,29 @@ class LabourRequestItem extends StatelessWidget {
             ],
           ).marginOnly(top: 15),
 
+          // 薪水
+          Row(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              MyTextView(
+                "${"Salary".tr}:",
+                isFontRegular: true,
+                textColor: ColorConstants.textGrayAECAE5,
+                fontSize: 14,
+              ),
+
+              //薪水
+              MyTextView(
+                item.salary ?? "-",
+                marginLeft: 5,
+                isFontRegular: true,
+                textColor: Colors.white,
+                fontSize: 14,
+              ).expanded(),
+            ],
+          ).marginOnly(top: 15),
+
           // 状态
           Row(
             mainAxisSize: MainAxisSize.max,
@@ -207,6 +255,25 @@ class LabourRequestItem extends StatelessWidget {
               mainAxisAlignment: MainAxisAlignment.end,
               crossAxisAlignment: CrossAxisAlignment.center,
               children: [
+                //Copy按钮
+                Visibility(
+                  visible: item.actionList?.contains("detail") ?? false,
+                  child: MyButton(
+                    onPressed: () {
+                      FocusScope.of(context).unfocus();
+                      onCopyAction?.call();
+                    },
+                    text: "Copy".tr,
+                    textColor: ColorConstants.white,
+                    backgroundColor: hexToColor(
+                      "#C009FC",
+                    ),
+                    radius: 17.25,
+                    minWidth: 60,
+                    minHeight: 35,
+                  ).marginOnly(left: 12),
+                ),
+
                 //详情按钮
                 Visibility(
                   visible: item.actionList?.contains("detail") ?? false,

+ 5 - 1
packages/cpt_uk/lib/modules/job/labour_request_list/labour_request_list_controller.dart

@@ -275,6 +275,11 @@ class LabourRequestListController extends GetxController with DioCancelableMixin
     UKLabourRequestAddPage.startInstance(1, data.requestId.toString());
   }
 
+  //去新增页面Copy
+  void gotoCopyPage(LabourRequestListRows data) {
+    UKLabourRequestAddPage.startInstance(0, data.requestId.toString());
+  }
+
   //去状态工作流的页面
   void gotoWorkflowPage(LabourRequestListRows data) {
     UKLabourRequestWorkflowPage.startInstance(data.requestId.toString());
@@ -291,5 +296,4 @@ class LabourRequestListController extends GetxController with DioCancelableMixin
     ));
   }
 
-
 }

+ 3 - 0
packages/cpt_uk/lib/modules/job/labour_request_list/labour_request_list_page.dart

@@ -150,6 +150,9 @@ class _LabourRequestListState extends BaseState<UKLabourRequestListPage, LabourR
                           onStatusAction: () {
                             controller.gotoWorkflowPage(state.datas[index]);
                           },
+                          onCopyAction: (){
+                            controller.gotoCopyPage(state.datas[index]);
+                          },
                         );
                       },
                       childCount: state.datas.length,

+ 0 - 1
packages/cpt_uk/lib/modules/job/template_add/template_add_controller.dart

@@ -1,4 +1,3 @@
-import 'package:domain/entity/response/job_template_edit_index_entity.dart';
 import 'package:domain/entity/response/u_k_template_detail_entity.dart';
 import 'package:domain/repository/uk_job_repository.dart';
 import 'package:get/get.dart';

+ 0 - 1
packages/cpt_uk/lib/modules/job/template_add/template_add_page.dart

@@ -11,7 +11,6 @@ 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';

+ 217 - 0
packages/cpt_uk/lib/widget/date_range_picker_dialog.dart

@@ -0,0 +1,217 @@
+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:plugin_basic/basic_export.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:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/picker/date_picker_util.dart';
+import 'package:widgets/widget_export.dart';
+
+class DateRangePickerDialog extends StatefulWidget {
+  final void Function(String) confirmAction; // 回调确认的时间区间
+  final VoidCallback? cancelAction;
+
+  DateRangePickerDialog({
+    required this.confirmAction,
+    this.cancelAction,
+  });
+
+  @override
+  _DateRangePickerDialogState createState() => _DateRangePickerDialogState();
+}
+
+class _DateRangePickerDialogState extends State<DateRangePickerDialog> {
+  DateTime? startDate;
+  DateTime? endDate;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        Container(
+          width: double.infinity,
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            children: [
+              MyTextView(
+                "Select Date Range".tr,
+                fontSize: 19,
+                isFontMedium: true,
+                textColor: ColorConstants.black,
+                marginTop: 15,
+                marginBottom: 15,
+              ),
+              InkWell(
+                onTap: () {
+                  DatePickerUtil.showCupertinoDatePicker(
+                    selectedDateTime: startDate ?? DateTime.now(),
+                    mode: CupertinoDatePickerMode.date,
+                    onDateTimeChanged: (date) {
+                      setState(() {
+                        startDate = date;
+                      });
+                    },
+                    title: "Start Time".tr,
+                  );
+                },
+                child: Container(
+                  decoration: const BoxDecoration(
+                    color: ColorConstants.grayECECEC,
+                    borderRadius: BorderRadius.all(Radius.circular(5)),
+                  ),
+                  margin: const EdgeInsets.symmetric(horizontal: 15),
+                  padding: const EdgeInsets.all(15.0),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      MyTextView(
+                        startDate != null ? DateTimeUtils.formatDate(startDate, format: 'yyyy-MM-dd') : "Select Start Time",
+                        fontSize: 15,
+                        isFontRegular: true,
+                        textColor: ColorConstants.black33,
+                      ),
+                      const MyAssetImage(
+                        Assets.cptJobPickDateIcon,
+                        width: 20,
+                        height: 20,
+                        color: ColorConstants.secondaryAppColor,
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              InkWell(
+                onTap: () {
+                  DatePickerUtil.showCupertinoDatePicker(
+                    selectedDateTime: endDate ?? DateTime.now(),
+                    mode: CupertinoDatePickerMode.date,
+                    onDateTimeChanged: (date) {
+                      setState(() {
+                        endDate = date;
+                      });
+                    },
+                    title: "End Time".tr,
+                  );
+                },
+                child: Container(
+                  decoration: const BoxDecoration(
+                    color: ColorConstants.grayECECEC,
+                    borderRadius: BorderRadius.all(Radius.circular(5)),
+                  ),
+                  margin: const EdgeInsets.only(left: 15, right: 15, top: 15),
+                  padding: const EdgeInsets.all(15.0),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      MyTextView(
+                        endDate != null ? DateTimeUtils.formatDate(endDate, format: 'yyyy-MM-dd') : "Select End Time",
+                        fontSize: 15,
+                        isFontRegular: true,
+                        textColor: ColorConstants.black33,
+                      ),
+                      const MyAssetImage(
+                        Assets.cptJobPickDateIcon,
+                        width: 20,
+                        height: 20,
+                        color: ColorConstants.secondaryAppColor,
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              Container(
+                margin: const EdgeInsets.only(top: 25),
+                color: const Color(0XFFCECECE),
+                height: 0.5,
+              ),
+              Row(
+                children: [
+                  Expanded(
+                      flex: 1,
+                      child: InkWell(
+                        onTap: () {
+                          onCancel();
+                          widget.cancelAction?.call();
+                        },
+                        child: MyTextView(
+                          "Cancel".tr,
+                          fontSize: 17.5,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: const Color(0XFF0085C4),
+                          cornerRadius: 3,
+                          borderWidth: 1,
+                        ),
+                      )),
+                  Container(
+                    color: const Color(0xff09141F).withOpacity(0.13),
+                    width: 0.5,
+                  ),
+                  Expanded(
+                      flex: 1,
+                      child: InkWell(
+                        onTap: () async {
+
+                          if (startDate != null && endDate != null) {
+                            if (endDate!.isBefore(startDate!.add(const Duration(hours: 6)))) {
+                              ToastEngine.show("End date must be greater than start date");
+                            }else{
+                              onCancel();
+                              // 确保开始日期和结束日期都已选择
+                              String dateRange = _getDateRange(startDate!, endDate!);
+                              widget.confirmAction(dateRange);
+                            }
+                          } else {
+                            ToastEngine.show("Select Date");
+                          }
+                        },
+                        child: MyTextView(
+                          "Confirm".tr,
+                          marginLeft: 10,
+                          fontSize: 17.5,
+                          isFontMedium: true,
+                          textAlign: TextAlign.center,
+                          textColor: const Color(0XFF0085C4),
+                          cornerRadius: 3,
+                        ),
+                      )),
+                ],
+              ).constrained(height: 46),
+            ],
+          ),
+        ),
+      ],
+    ).constrained(width: 295);
+  }
+
+  String _getDateRange(DateTime start, DateTime end) {
+    List<String> dateList = [];
+    DateTime current = start;
+    String endFormat = DateTimeUtils.formatDate(end, format: 'yyyy-MM-dd');
+
+    // 逐日增加,直到达到结束日期,包括结束日期
+    while (current.isBefore(end) || current.isAtSameMomentAs(end)) {
+      dateList.add(DateTimeUtils.formatDate(current, format: 'yyyy-MM-dd'));
+      current = current.add(const Duration(days: 1));
+    }
+
+    if (!dateList.contains(endFormat)) {
+      dateList.add(endFormat);
+    }
+
+    return dateList.join(','); // 使用逗号连接日期
+  }
+
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

+ 5 - 0
packages/cs_domain/lib/entity/response/labour_request_list_entity.dart

@@ -30,6 +30,11 @@ class LabourRequestListRows {
   String? departmentName;
   @JSONField(name: "job_time")
   String? jobTime;
+  @JSONField(name: "job_full_time")
+  String? jobFullTime;
+  @JSONField(name: "job_date")
+  String? jobDate;
+  String? salary;
   @JSONField(name: "need_num")
   int needNum = 0;
   @JSONField(name: "co_status")

+ 21 - 0
packages/cs_domain/lib/generated/json/labour_request_list_entity.g.dart

@@ -51,6 +51,18 @@ LabourRequestListRows $LabourRequestListRowsFromJson(Map<String, dynamic> json)
   if (jobTime != null) {
     labourRequestListRows.jobTime = jobTime;
   }
+  final String? jobFullTime = jsonConvert.convert<String>(json['job_full_time']);
+  if (jobFullTime != null) {
+    labourRequestListRows.jobFullTime = jobFullTime;
+  }
+  final String? jobDate = jsonConvert.convert<String>(json['job_date']);
+  if (jobDate != null) {
+    labourRequestListRows.jobDate = jobDate;
+  }
+  final String? salary = jsonConvert.convert<String>(json['salary']);
+  if (salary != null) {
+    labourRequestListRows.salary = salary;
+  }
   final int? needNum = jsonConvert.convert<int>(json['need_num']);
   if (needNum != null) {
     labourRequestListRows.needNum = needNum;
@@ -85,6 +97,9 @@ Map<String, dynamic> $LabourRequestListRowsToJson(LabourRequestListRows entity)
   data['job_title'] = entity.jobTitle;
   data['department_name'] = entity.departmentName;
   data['job_time'] = entity.jobTime;
+  data['job_full_time'] = entity.jobFullTime;
+  data['job_date'] = entity.jobDate;
+  data['salary'] = entity.salary;
   data['need_num'] = entity.needNum;
   data['co_status'] = entity.coStatus;
   data['co_status_show'] = entity.coStatusShow;
@@ -100,6 +115,9 @@ extension LabourRequestListRowsExtension on LabourRequestListRows {
     String? jobTitle,
     String? departmentName,
     String? jobTime,
+    String? jobFullTime,
+    String? jobDate,
+    String? salary,
     int? needNum,
     int? coStatus,
     String? coStatusShow,
@@ -112,6 +130,9 @@ extension LabourRequestListRowsExtension on LabourRequestListRows {
       ..jobTitle = jobTitle ?? this.jobTitle
       ..departmentName = departmentName ?? this.departmentName
       ..jobTime = jobTime ?? this.jobTime
+      ..jobFullTime = jobFullTime ?? this.jobFullTime
+      ..jobDate = jobDate ?? this.jobDate
+      ..salary = salary ?? this.salary
       ..needNum = needNum ?? this.needNum
       ..coStatus = coStatus ?? this.coStatus
       ..coStatusShow = coStatusShow ?? this.coStatusShow

+ 48 - 0
packages/cs_domain/lib/repository/uk_job_repository.dart

@@ -191,4 +191,52 @@ class UKJobRepository extends GetxService {
     }
     return result.convert();
   }
+
+  /// 添加用工请求发布
+  Future<HttpResult> addLabourRequestSubmit({
+    required String? templateId,
+    required String? jobDate,
+    required String? startTime,
+    required String? endTime,
+    required String? departmentId,
+    required String? needNum,
+    required String? salaryBy,
+    String? amount,
+    String? repeatDate,
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params['template_id'] = templateId ?? "";
+    params['job_date'] = jobDate ?? "";
+    params['start_time'] = startTime ?? "";
+    params['end_time'] = endTime ?? "";
+    params['need_num'] = needNum ?? "";
+    params['salary_by'] = salaryBy ?? "";
+    if (!Utils.isEmpty(departmentId)) {
+      params["co_department_id"] = departmentId!;
+    }
+    if (!Utils.isEmpty(amount)) {
+      params["amount"] = amount!;
+    }
+    if (!Utils.isEmpty(repeatDate)) {
+      params["select"] = repeatDate!;
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiLabourRequestAddSubmit,
+      method: HttpMethod.POST,
+      params: params,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      return result.convert();
+    }
+    return result.convert();
+  }
 }

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

@@ -299,6 +299,10 @@ const Map<String, String> en_US = {
   'Malaysia': 'Malaysia',
   'Netherlands': 'Netherlands',
   'Retake': 'Retake',
+  'Salary': 'Salary',
+  'Copy': 'Copy',
+  'Amount': 'Amount',
+  'Repeat Date': 'Repeat Date',
 
   //插件的国际化
   'Pull to refresh': 'Pull to refresh',

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

@@ -299,6 +299,10 @@ const Map<String, String> zh_CN = {
   'Malaysia': '马来西亚',
   'Netherlands': '荷兰',
   'Retake': '重新获取',
+  'Salary': '薪水',
+  'Copy': '复制',
+  'Amount': '金额',
+  'Repeat Date': '重复日期',
 
   //插件的国际化
   'Pull to refresh': '下拉刷新',