Ver código fonte

马来的签到员工列表与签到逻辑

liukai 4 dias atrás
pai
commit
f26ccc35da

+ 2 - 1
packages/cpt_ms/lib/modules/job/sign_camera/sign_camera_controller.dart

@@ -13,7 +13,8 @@ class SignCameraController extends GetxController {
 
   /// 确认图片
   void confirmImage() {
-
+    state.cb?.call(state.watermarkedFile);
+    Get.back();
   }
 
 }

+ 5 - 3
packages/cpt_ms/lib/modules/job/sign_camera/sign_camera_page.dart

@@ -33,8 +33,8 @@ class SignCameraPage extends BaseStatefulPage<SignCameraController> {
   SignCameraPage({super.key});
 
   //启动当前页面
-  static void startInstance() {
-    return Get.start(RouterPath.MSSignCamera);
+  static void startInstance(void Function(String? path)? cb) {
+    return Get.start(RouterPath.MSSignCamera, arguments: {'cb': cb});
   }
 
   @override
@@ -58,6 +58,7 @@ class _SignCameraPageState extends BaseState<SignCameraPage, SignCameraControlle
   void initState() {
     super.initState();
     state = controller.state;
+    state.cb = Get.arguments['cb'] as void Function(String?)?;
     _initCamera(); // 初始化摄像头
   }
 
@@ -103,6 +104,7 @@ class _SignCameraPageState extends BaseState<SignCameraPage, SignCameraControlle
     // 2. 选择摄像头(优先选前置镜头)
     CameraDescription frontCamera = _cameras!.firstWhere((cam) => cam.lensDirection == CameraLensDirection.front);
 
+
     // 3. 初始化控制器(分辨率选 medium,平衡性能和画质)
     _controller = CameraController(
       frontCamera,
@@ -113,6 +115,7 @@ class _SignCameraPageState extends BaseState<SignCameraPage, SignCameraControlle
     await _controller.initialize();
 
     if (mounted) {
+
       setState(() {
         _isCameraInitialized = true;
       });
@@ -265,7 +268,6 @@ class _SignCameraPageState extends BaseState<SignCameraPage, SignCameraControlle
 
       // -------- 步骤2:生成水印文本(时间) --------
       String watermarkText = DateTimeUtils.formatNowDateStr(format: 'yyyy-MM-dd HH:mm');
-      // (需确保 DateTimeUtils 工具类能正确返回时间字符串)
 
       // -------- 步骤3:准备绘制字体 --------
       img.drawString(originalImage, img.arial_24, 20, 20, watermarkText);

+ 1 - 0
packages/cpt_ms/lib/modules/job/sign_camera/sign_camera_state.dart

@@ -2,4 +2,5 @@ class SignCameraState {
 
  String? watermarkedFile;  //最终拍摄处理后的图片
 
+ void Function(String? path)? cb;
 }

+ 31 - 25
packages/cpt_ms/lib/modules/job/sign_in_sign_out/sign_in_sign_out_controller.dart

@@ -5,9 +5,11 @@ import 'package:domain/entity/response/sign_in_sign_out_entity.dart';
 import 'package:domain/repository/ms_repository.dart';
 import 'package:get/get.dart';
 import 'package:plugin_platform/engine/permission/permission_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 
 import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
 import 'package:shared/utils/date_time_utils.dart';
+import 'package:shared/utils/util.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/picker/date_picker_util.dart';
 import 'package:widgets/widget_export.dart';
@@ -96,31 +98,27 @@ class SignInSignOutController extends GetxController with DioCancelableMixin {
   }
 
   /// 签到签出
-  void requestCheckInCheckOut(bool isCheckIn, SignInSignOutRows item, ByteData byteData) async {
+  void requestCheckInCheckOut(String? type, SignInSignOutRows? item, String? path) async {
     //请求接口
+    var result = await _msRepository.signImageSubmit(
+      item?.appliedId,
+      path,
+      type,
+      cancelToken: cancelToken,
+    );
 
-    // var result = await _jobRepository.submitCheckInOut(
-    //   item.appliedId.toString(),
-    //   byteData,
-    //   isCheckIn: isCheckIn,
-    //   cancelToken: cancelToken,
-    // );
-    //
-    // if (result.isSuccess) {
-    //   CheckSuccessEntity entity = result.data!;
-    //   if (isCheckIn) {
-    //     item.checkInImg = entity.checkImg;
-    //     item.checkInTime = entity.checkTime;
-    //   } else {
-    //     item.checkOutImg = entity.checkImg;
-    //     item.checkOutTime = entity.checkTime;
-    //   }
-    //   //更新状态
-    //   update();
-    // } else {
-    //   errorMessage = result.errorMsg;
-    //   ToastEngine.show(errorMessage ?? "Network Load Error".tr);
-    // }
+    if (result.isSuccess) {
+      SignInSignOutRows entity = result.data!;
+      item?.inTime = entity.inTime;
+      item?.inPhoto = entity.inPhoto;
+      item?.outTime = entity.outTime;
+      item?.outPhoto = entity.outPhoto;
+      //更新状态
+      update();
+    } else {
+      errorMessage = result.errorMsg;
+      ToastEngine.show(errorMessage ?? "Network Load Error".tr);
+    }
   }
 
   //执行搜索
@@ -144,14 +142,22 @@ class SignInSignOutController extends GetxController with DioCancelableMixin {
   /// 用户签到
   void userSignIn(SignInSignOutRows item) {
     PermissionEngine().requestCameraPermission(() {
-      SignCameraPage.startInstance();
+      SignCameraPage.startInstance((path) {
+        if (Utils.isNotEmpty(path)) {
+          requestCheckInCheckOut('in', item, path);
+        }
+      });
     });
   }
 
   /// 用户签出
   void userSignOut(SignInSignOutRows item) {
     PermissionEngine().requestCameraPermission(() {
-      SignCameraPage.startInstance();
+      SignCameraPage.startInstance((path) {
+        if (Utils.isNotEmpty(path)) {
+          requestCheckInCheckOut('out', item, path);
+        }
+      });
     });
   }
 

+ 75 - 62
packages/cpt_ms/lib/modules/job/sign_in_sign_out/sign_in_sign_out_page.dart

@@ -11,6 +11,7 @@ import 'package:plugin_basic/base/base_stateful_page.dart';
 import 'package:plugin_basic/base/base_state.dart';
 import 'package:plugin_basic/base/mixin_state_lifecycle.dart';
 import 'package:plugin_basic/utils/ext_get_nav.dart';
+import 'package:plugin_platform/engine/image/image_preview.dart';
 import 'package:router/path/router_path.dart';
 import 'package:shared/utils/date_time_utils.dart';
 import 'package:shared/utils/log_utils.dart';
@@ -214,10 +215,10 @@ class _SignInSignOutPageState extends BaseState<SignInSignOutPage, SignInSignOut
     final item = controller.datas[index];
 
     return Container(
-      padding: EdgeInsets.only(left: 23, right: 12),
-      margin: EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
+      padding: const EdgeInsets.only(left: 23, right: 12),
+      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(
@@ -330,36 +331,42 @@ class _SignInSignOutPageState extends BaseState<SignInSignOutPage, SignInSignOut
                       mainAxisAlignment: MainAxisAlignment.start,
                       crossAxisAlignment: CrossAxisAlignment.center,
                       children: [
-                        Container(
-                          width: 90,
-                          height: 35,
-                          margin: const EdgeInsets.only(top: 18),
-                          decoration: BoxDecoration(
-                            color: Utils.isEmpty(item.inPhoto) ? const Color(0xFF56AAFF) : ColorConstants.white,
-                            borderRadius: BorderRadius.circular(17.25), // 设置圆角
-                          ),
-                          child: Stack(
-                            alignment: Alignment.center,
-                            children: [
-                              Visibility(
-                                visible: Utils.isEmpty(item.inPhoto),
-                                child: MyTextView(
-                                  "Check In".tr,
-                                  isFontMedium: true,
-                                  textColor: ColorConstants.white,
-                                  fontSize: 14,
+                        Stack(
+                          alignment: Alignment.center,
+                          children: [
+                            Visibility(
+                              visible: Utils.isEmpty(item.inPhoto),
+                              child: Container(
+                                width: 90,
+                                height: 35,
+                                decoration: BoxDecoration(
+                                  color: Utils.isEmpty(item.inPhoto) ? const Color(0xFF56AAFF) : ColorConstants.white,
+                                  borderRadius: BorderRadius.circular(17.25), // 设置圆角
+                                ),
+                                child: Center(
+                                  child: MyTextView(
+                                    "Check In".tr,
+                                    isFontMedium: true,
+                                    textColor: ColorConstants.white,
+                                    fontSize: 14,
+                                  ),
                                 ),
-                              ),
-                              Visibility(
-                                visible: !Utils.isEmpty(item.inPhoto),
-                                child: MyLoadImage(item.inPhoto, width: 71.5, height: 25, fit: BoxFit.cover),
-                              ),
-                            ],
-                          ).onTap(() {
-                            if (Utils.isEmpty(item.inPhoto)) {
-                              controller.userSignIn(item);
-                            }
-                          }),
+                              ).onTap(() {
+                                if (Utils.isEmpty(item.inPhoto)) {
+                                  controller.userSignIn(item);
+                                }
+                              }),
+                            ),
+                            Visibility(
+                              visible: Utils.isNotEmpty(item.inPhoto),
+                              child: Hero(
+                                tag: '112cc8a34e13$index',
+                                child: MyLoadImage(item.inPhoto, width: 60, height: 60, fit: BoxFit.cover, cornerRadius: 5),
+                              ).onTap(() {
+                                ImagePreviewEngine.singleImagePreview(context, item.inPhoto!, heroTag: '112cc8a34e13$index');
+                              }),
+                            ),
+                          ],
                         ),
                         Visibility(
                           visible: !Utils.isEmpty(item.inTime),
@@ -379,36 +386,42 @@ class _SignInSignOutPageState extends BaseState<SignInSignOutPage, SignInSignOut
                       mainAxisAlignment: MainAxisAlignment.start,
                       crossAxisAlignment: CrossAxisAlignment.center,
                       children: [
-                        Container(
-                          width: 90,
-                          height: 35,
-                          margin: EdgeInsets.only(top: 18),
-                          decoration: BoxDecoration(
-                            color: Utils.isEmpty(item.outPhoto) ? Color(0xFF56AAFF) : ColorConstants.white,
-                            borderRadius: BorderRadius.circular(17.25), // 设置圆角
-                          ),
-                          child: Stack(
-                            alignment: Alignment.center,
-                            children: [
-                              Visibility(
-                                visible: Utils.isEmpty(item.outPhoto),
-                                child: MyTextView(
-                                  "Check Out".tr,
-                                  isFontMedium: true,
-                                  textColor: ColorConstants.white,
-                                  fontSize: 14,
+                        Stack(
+                          alignment: Alignment.center,
+                          children: [
+                            Visibility(
+                              visible: Utils.isEmpty(item.outPhoto),
+                              child: Container(
+                                width: 90,
+                                height: 35,
+                                decoration: BoxDecoration(
+                                  color: Utils.isEmpty(item.outPhoto) ? const Color(0xFF56AAFF) : ColorConstants.white,
+                                  borderRadius: BorderRadius.circular(17.25), // 设置圆角
+                                ),
+                                child: Center(
+                                  child: MyTextView(
+                                    "Check Out".tr,
+                                    isFontMedium: true,
+                                    textColor: ColorConstants.white,
+                                    fontSize: 14,
+                                  ),
                                 ),
-                              ),
-                              Visibility(
-                                visible: !Utils.isEmpty(item.outPhoto),
-                                child: MyLoadImage(item.outPhoto, width: 71.5, height: 25, fit: BoxFit.cover),
-                              ),
-                            ],
-                          ).onTap(() {
-                            if (Utils.isEmpty(item.outPhoto)) {
-                              controller.userSignOut(item);
-                            }
-                          }),
+                              ).onTap(() {
+                                if (Utils.isEmpty(item.outPhoto)) {
+                                  controller.userSignOut(item);
+                                }
+                              }),
+                            ),
+                            Visibility(
+                              visible: Utils.isNotEmpty(item.outPhoto),
+                              child: Hero(
+                                tag: '112cc8a34e13$index',
+                                child: MyLoadImage(item.outPhoto, width: 60, height: 60, fit: BoxFit.cover, cornerRadius: 5),
+                              ).onTap(() {
+                                ImagePreviewEngine.singleImagePreview(context, item.outPhoto!, heroTag: '112cc8a34e13$index');
+                              }),
+                            ),
+                          ],
                         ),
                         Visibility(
                           visible: !Utils.isEmpty(item.outTime),
@@ -423,7 +436,7 @@ class _SignInSignOutPageState extends BaseState<SignInSignOutPage, SignInSignOut
                       ],
                     ).marginOnly(left: 10),
                   ],
-                ),
+                ).marginOnly(top: 18),
 
                 const SizedBox(height: 18),
               ],

+ 1 - 1
packages/cs_domain/lib/constants/api_constants.dart

@@ -505,6 +505,6 @@ class ApiConstants {
   static const apiSignListMS = "/index.php/api/v1/er/sign/table";
 
   //签到保存
-  static const apiSignSaveMS = "/index.php/api/v1/er/sing/save";
+  static const apiSignSaveMS = "/index.php/api/v1/er/sign/save";
 
 }

+ 35 - 2
packages/cs_domain/lib/repository/ms_repository.dart

@@ -37,15 +37,48 @@ class MSRepository extends GetxService {
       cancelToken: cancelToken,
     );
 
-    //根据返回的结果,封装原始数据为Bean/Entity对象
     if (result.isSuccess) {
       //重新赋值data或list
       final json = result.getDataJson();
       var data = SignInSignOutEntity.fromJson(json!);
-      //重新赋值data或list
       return result.convert<SignInSignOutEntity>(data: data);
     }
     return result.convert();
   }
 
+  /// 提交考勤的拍照图片
+  Future<HttpResult<SignInSignOutRows>> signImageSubmit(
+    String? appliedId,
+    String? photo,
+    String? type, {
+    CancelToken? cancelToken,
+  }) async {
+    //参数
+    Map<String, String> params = {};
+    params['applied_id'] = appliedId ?? "";
+    params['type'] = type ?? "";
+
+    Map<String, String> paths = {};
+    if (!Utils.isEmpty(photo)) {
+      paths["photo"] = photo ?? "";
+    }
+
+    final result = await httpProvider.requestNetResult(
+      ApiConstants.apiSignSaveMS,
+      method: HttpMethod.POST,
+      params: params,
+      paths: paths,
+      networkDebounce: true,
+      isShowLoadingDialog: true,
+      cancelToken: cancelToken,
+    );
+
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = SignInSignOutRows.fromJson(json!);
+      return result.convert<SignInSignOutRows>(data: data);
+    }
+    return result.convert();
+  }
 }