From db0dc664548dff6613882997a11019248933c8d8 Mon Sep 17 00:00:00 2001 From: liutong <836164388@qq.com> Date: Thu, 12 Jun 2025 16:46:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor(attendance):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=91=98=E5=B7=A5=E8=80=83=E5=8B=A4=E7=BC=96=E8=BE=91=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构了 edit 方法,支持多种考勤状态的处理 - 增加了对签到、签退和请假的单独处理逻辑 - 优化了参数验证和错误提示 - 调整了查询条件,支持按状态和签退时间查询 --- .../controller/apiController/Attendance.php | 145 ++++++++++-------- .../apiController/CustomerResources.php | 2 +- .../api/apiService/AttendanceService.php | 12 ++ 3 files changed, 96 insertions(+), 63 deletions(-) diff --git a/niucloud/app/api/controller/apiController/Attendance.php b/niucloud/app/api/controller/apiController/Attendance.php index 704874cf..a3a0a87f 100644 --- a/niucloud/app/api/controller/apiController/Attendance.php +++ b/niucloud/app/api/controller/apiController/Attendance.php @@ -42,9 +42,12 @@ class Attendance extends BaseApiService //员工考勤-编辑(员工打卡/请假/签退) public function edit(Request $request){ + $id =$request->param('id','');//考勤表id $campus_id =$request->param('campus_id','');//校区ID $staff_id =$this->member_id;//人员ID $attendance_date =$request->param('attendance_date','');//考勤日期 + $leave_start_time =$request->param('leave_start_time','');//请假开始时间 + $leave_end_time =$request->param('leave_end_time','');//请假结束时间 $remarks =$request->param('remarks','');//备注 $status =$request->param('status','');//考勤状态: present-出勤, absent-缺勤, late-迟到, leave_early-早退,leave-请假,sign_out-签退 $longitude = $request->param('longitude','');//经度 @@ -56,106 +59,124 @@ class Attendance extends BaseApiService return fail('缺少定位坐标'); } - if(empty($campus_id) || empty($attendance_date) || empty($status)){ + if(empty($attendance_date) || empty($status)){ return fail('缺少参数'); } + if(!in_array($status,['present','absent','late','leave_early','leave','sign_out'])){ return fail('状态类型不正确'); } - //获取校区的经纬度坐标 - $campus_data = (new CampusService)->getInfo($campus_id);//查校区详情 - $campus_lng = $campus_data['campus_coordinates']['lng'];//校区经度坐标 - $campus_lat = $campus_data['campus_coordinates']['lat'];//校区纬度坐标 - $radius = 1500.0;//打卡半径(米) //判断签到+签退时是否超出打卡范围 - if(in_array($status,['present','sign_out'])){ - $isInCheckRange = (new CommonService())->isInCheckRange((float)$campus_lng, (float)$campus_lat, (float)$longitude, (float)$latitude, (float)$radius); + if(in_array($status,['present','sign_out']) && !empty($campus_id)){ + //获取校区的经纬度坐标 + $campus_data = (new CampusService)->getInfo($campus_id);//查校区详情 + $campus_lng = $campus_data['campus_coordinates']['lng'];//校区经度坐标 + $campus_lat = $campus_data['campus_coordinates']['lat'];//校区纬度坐标 + $radius = 1500.0;//打卡半径(米) + + $isInCheckRange = (new CommonService())->isInCheckRange((float)$campus_lng, (float)$campus_lat, (float)$longitude, (float)$latitude, (float)$radius);//判断是否在打卡范围内 if(!$isInCheckRange){ return fail("超出打卡范围,规定打卡范围({$radius}米)"); } } - - //查询数据是否存在,一天一个校区同一个人只能产生一条数据 + //查询数据是否存在,一天一个校区同一个人可能有多条打卡记录数据,只要有1条打卡没签退就不能新增新的打卡记录 $date_h = date('H:i:s'); $obj = (new AttendanceService()); $info = $obj->info([ + 'id'=>$id, 'campus_id'=>$campus_id, 'staff_id'=>$staff_id, 'attendance_date'=>$attendance_date, ])['data']; - //如果是签退的时候就是修改 - if($status == 'sign_out'){ - if (($info['status'] ?? '') != 'present') { - return fail('未查询到今日签到信息,无法签退'); + //判断是打卡 + if($status == 'present'){ + $model = new \app\model\attendance\Attendance(); + $model = $model->where('staff_id',$staff_id)->where('status','present'); + if($campus_id === '0' || $campus_id === 0 || !empty($campus_id)){ + $model = $model->where('campus_id',$campus_id); + } + if(!empty($attendance_date)){ + $model = $model->where('attendance_date',$attendance_date); + } + + // 获取今天所有考勤记录 + $records = $model->order('id', 'desc')->select()->toArray(); + // Step 1: 检查是否有未签退的记录 + foreach ($records as $record) { + if (empty($record['check_out_time'])) { + return fail('今日有签到记录未签退,请先签退后再试'); + } + } + + //插入打卡记录 + $data = [ + 'campus_id'=>$campus_id ?? 0,// + 'staff_id'=>$staff_id,// + 'attendance_date'=>$attendance_date,// + 'check_in_time'=>$date_h,// + 'status'=>$status,// + 'coordinate'=>$coordinate,//坐标|经度,纬度 + 'remarks'=>$remarks,// + ]; + $res = $obj->addData($data); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); + } + //判断是签退 + if($status == 'sign_out'){ + if($info['attendance_date'] != $attendance_date && $info['status'] != 'present'){ + return fail('为找到今日签到记录'); } //签退的情况 $where = [ - 'id'=>$info['id'] + 'id'=>$info['id'] ]; $data = [ 'check_out_time'=>$date_h,//签退时间 'coordinate'=>$coordinate,//坐标|经度,纬度 + 'remarks' => $remarks,// ]; //执行修改操作 $res = $obj->editData($where,$data); - }else{ - //如果是签到/请假 - $data = [ - 'campus_id'=>$campus_id,//校区ID - 'staff_id'=>$staff_id,//人员ID - 'attendance_date'=>$attendance_date,//考勤日期 - 'coordinate'=>$coordinate,//坐标|经度,纬度 - 'status'=>$status,//考勤状态 - ]; - //如果是签到的情况 - if($info){ - if($status == 'present' && $info['status'] == 'present'){ - //更新签到数据 - //执行修改操作 - $edit_data = [ - 'check_in_time'=>$date_h,//签到时间 - 'coordinate'=>$coordinate,//坐标|经度,纬度 - 'status'=>$status//考勤状态 - ]; - $res = $obj->editData(['id'=>$info['id']],$edit_data); - if(!$res['code']){ - return fail($res['msg']); - } - return success($res['data']); - } - $status_arr = (new \app\model\attendance\Attendance())::STATUS; - $status_name = $status_arr[$info['status']] ?? ''; - if(!$status_name){ - $status_name = '考勤'; - } - return fail("今日已{$status_name}重复操作"); - }else{ - $data['check_in_time'] = $date_h;//签到时间 - if($remarks){ - $data['remarks'] = $remarks; - } - //执行创建操作 - $res = $obj->addData($data); - if(!$res['code']){ - return fail($res['msg']); - } - return success($res['data']); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); + } + //判断是请假 + if($status == 'leave'){ + //判断今日是否存在打卡记录,判断今日的打开记录是否已经签退,是则不可以再请假了 + if($info && $info['status'] == 'present' && $info['attendance_date'] == $attendance_date && !empty($info['check_out_time'])){ + return fail('今日已签退,无法进行请假操作'); } + $data = [ + 'campus_id' => $campus_id ?? 0, + 'staff_id' => $staff_id, + 'attendance_date' => $attendance_date, + 'leave_start_time' => $leave_start_time, + 'leave_end_time' => $leave_end_time, + 'status' => $status, + 'coordinate' => $coordinate, + 'remarks' => $remarks, + ]; - - - - - + //创建请假记录 + $res = $obj->addData($data); + if(!$res['code']){ + return fail($res['msg']); + } + return success($res['data']); } } } diff --git a/niucloud/app/api/controller/apiController/CustomerResources.php b/niucloud/app/api/controller/apiController/CustomerResources.php index 7f7072fe..f58175ec 100644 --- a/niucloud/app/api/controller/apiController/CustomerResources.php +++ b/niucloud/app/api/controller/apiController/CustomerResources.php @@ -166,7 +166,7 @@ class CustomerResources extends BaseApiService "preferred_class_time" => $optional_class_time,//可选上课时间 "distance" => $request->param('distance', ''),//距离 "communication" => $request->param('communication', ''),//沟通备注 - "staff_id" => $request->param('staff_id', ''),//人员ID + "staff_id" => $request->param('staff_id', ''),//人员ID//如果没有就是当前登录人的员工id "first_visit_status" => $request->param('first_visit_status', null),//一访情况 "second_visit_status" => $request->param('second_visit_status', null),//二访情况 diff --git a/niucloud/app/service/api/apiService/AttendanceService.php b/niucloud/app/service/api/apiService/AttendanceService.php index 1eb2a255..883168af 100644 --- a/niucloud/app/service/api/apiService/AttendanceService.php +++ b/niucloud/app/service/api/apiService/AttendanceService.php @@ -91,6 +91,18 @@ class AttendanceService extends BaseApiService if (!empty($where['attendance_date'])) { $model = $model->where('attendance_date', $where['attendance_date']); } + if(!empty($where['status'])){ + $model = $model->where('status', $where['status']); + } + if(!empty($where['check_out_time'])){ + if($where['check_out_time'] === 'null'){ + $where['check_out_time'] = null; + $model = $model->where('check_out_time', null); + }else{ + $model = $model->whereIn('check_out_time', $where['check_out_time']); + } + + } $data = $model->field($field)->find(); if ($data) { $res = [