|
|
|
@ -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,44 +59,82 @@ 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('状态类型不正确'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//判断签到+签退时是否超出打卡范围 |
|
|
|
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;//打卡半径(米) |
|
|
|
|
|
|
|
//判断签到+签退时是否超出打卡范围 |
|
|
|
if(in_array($status,['present','sign_out'])){ |
|
|
|
$isInCheckRange = (new CommonService())->isInCheckRange((float)$campus_lng, (float)$campus_lat, (float)$longitude, (float)$latitude, (float)$radius); |
|
|
|
$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('为找到今日签到记录'); |
|
|
|
} |
|
|
|
|
|
|
|
//签退的情况 |
|
|
|
@ -103,59 +144,39 @@ class Attendance extends BaseApiService |
|
|
|
$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 = '考勤'; |
|
|
|
//判断是请假 |
|
|
|
if($status == 'leave'){ |
|
|
|
//判断今日是否存在打卡记录,判断今日的打开记录是否已经签退,是则不可以再请假了 |
|
|
|
if($info && $info['status'] == 'present' && $info['attendance_date'] == $attendance_date && !empty($info['check_out_time'])){ |
|
|
|
return fail('今日已签退,无法进行请假操作'); |
|
|
|
} |
|
|
|
return fail("今日已{$status_name}重复操作"); |
|
|
|
}else{ |
|
|
|
$data['check_in_time'] = $date_h;//签到时间 |
|
|
|
if($remarks){ |
|
|
|
$data['remarks'] = $remarks; |
|
|
|
} |
|
|
|
//执行创建操作 |
|
|
|
|
|
|
|
$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']); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|