where('user_id',$userId)->where('day',$day)->find(); if($info){ // 当日班次存在直接返回 return $info; } // 查看当日是否排班 $class = model('AttendanceGroupClass')->getClassByDay($userId); // 当日不存在,获取昨日未结束班次,看看昨日班次是否跨天 $info = Db::name('attendance_user_class')->where('user_id',$userId)->where('status',0)->where('next',1)->where('day',$yday)->find(); if($info){ // 检查此跨天班次是否已结束 if(!$class){ // 今天没有班次 return $info; // 存在昨日跨天班次,直接返回 } // 获取昨天班次的最后下班时间 $lcontent = json_decode($info['content'],true); $lastTime = strtotime($lcontent[count($lcontent)-1]['etime']); $content = json_decode($class['content'],true); $date = $content['dates']; $firstTime = strtotime(date('Y-m-d').$date[0]['stime']); $fgTime = $lastTime + ($firstTime - $lastTime)/2; // 间隔时间 if($fgTime <= time()){ // 大于一半时间,结束上个班次,开启本班次 // 结束上个班次 $ycontent = json_decode($info['content'],true); foreach ($ycontent as $k=>$v){ $ycontent[$k]['sstatus'] = 1; $ycontent[$k]['estatus'] = 1; } $res = Db::name('attendance_user_class')->where('id',$info['id'])->update([ 'content' => json_encode($ycontent), 'status' => 1, 'update_time' => date('Y-m-d H:i:s') ]); if(!$res){ // 状态修改失败,直接抛出错误,终止程序 \exception('状态修改失败'); } // 添加今日班次 $ret = $this->saveGroupClass($userId,$class); return $ret; }else{ // 昨天班次可继续打卡 return $info; } }else{ // 添加今日班次 if(!$class){ // 今天没有班次 return false; } $ret = $this->saveGroupClass($userId,$class); return $ret; } } public function saveGroupClass($userId,$class){ $day = date('Y-m-d'); $nday = date('Y-m-d',strtotime($day) + 86400); // 只添加记录,不牵扯打卡 $content = json_decode($class['content'],true); $dates = $content['dates']; $newdates = []; //[{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}] $next = 0; foreach ($dates as $k=>$v){ $newdates[] = [ "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00', "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00', "sstatus" => 0, "estatus" => 0, "ssign" => "", "esign" => "" ]; if($v['snext'] == 1||$v['enext'] == 1){ $next = 1; } } $userData = [ 'user_id' => $userId, 'group_id' => $class['group_id'], 'class_id' => $class['class_id'], 'org_id' => $class['org_id'], 'content' => json_encode($newdates), 'create_time' => date('Y-m-d H:i:s'), 'day' => $day, 'next' => $next, 'status' => 0, 'duration' => 0 ]; $userClassId = Db::name('attendance_user_class')->insertGetId($userData); if(!$userClassId){ // 添加失败,直接抛出错误,终止程序 \exception('添加今日班次失败'); } $userData['id'] = $userClassId; return $userData; } public function info($userId,$day){ //content [{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}] 0=未结束 1=已结束 $info = Db::name('attendance_user_class')->where('user_id',$userId)->where('day',$day)->find(); if($info){ $info['content'] = json_decode($info['content'],true); } return $info; } public function info_old($userId,$day){ //content [{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}] 0=未结束 1=已结束 $info = Db::name('attendance_user_class')->where('user_id',$userId)->where('day',$day)->find(); if($info){ $info['content'] = json_decode($info['content'],true); // $lists = Db::name('attendance_record')->where('user_class_id',$info['id'])->order('id asc')->select(); // $lists = $lists?$lists:[]; // foreach ($info['content'] as $k=>$v){ // $sub = $eub = []; // foreach ($lists as $kk=>$vv){ // if($vv['kq_time'] == $v['stime']){ // $sub[] = $vv; // }else if($vv['kq_time'] == $v['etime']){ // $eub[] = $vv; // } // } // $info['content'][$k]['slist'] = $sub; // $info['content'][$k]['elist'] = $eub; // } } return $info; } // 改变打卡状态 public function changeAttendance($data,$orgId){ $info = Db::name('attendance_user_class')->where('id',$data['id'])->find(); if(!$info){ HelpHander::error('参数错误'); } if($info['status'] == 0){ HelpHander::error('无权限操作'); } if($data['cate'] == 1){ // 上班(正常上班/下班的记录是不可修改的) $ret = Db::name('attendance_record') ->where('user_id',$info['user_id']) ->where('create_time',$data['time']) ->where('cate',1) ->where('effective',1) ->where('status',0) ->find(); if($ret){ HelpHander::error('上班打卡为正常状态,不能修改'); } }else if($data['cate'] == 2){// 下班 $ret = Db::name('attendance_record') ->where('user_id',$info['user_id']) ->where('user_class_id',$data['id']) ->where('create_time',$data['time']) ->where('cate',2) ->where('effective',1) ->where('status',0) ->find(); if($ret){ HelpHander::error('下班打卡为正常状态,不能修改'); } } if($data['type'] == 1){ $data['min'] = 0; } $signdate = $data['time']; $status = 0; $result = '管理员修改为:正常'; if($data['cate'] == 1 && $data['type'] == 2){ //上班 $signdate = date('Y-m-d H:i:s',strtotime($data['time']) + $data['min']*60); $status = 1; $result = '管理员修改为:迟到'; }else if($data['cate'] == 2 && $data['type'] == 2){ $signdate = date('Y-m-d H:i:s',strtotime($data['time']) - $data['min']*60); $status = 2; $result = '管理员修改为:早退'; } Db::startTrans(); try{ Db::name('attendance_record') ->where('user_class_id',$data['id']) ->where('user_id',$info['user_id']) ->where('kq_time',$data['time']) ->update(['effective' => 0,'result'=>"打卡无效:此记录已被更新"]); $rdata = [ 'kq_time' => $data['time'], 'user_id' => $info['user_id'], 'org_id' => $info['org_id'], 'type' => 4, 'from' => '管理员修改', 'result' => $result, 'create_time' => $signdate, 'user_class_id' => $data['id'], 'effective' => 1, 'status' => $status, 'cate' => $data['cate'], 'duration' => $data['min']*60 ]; $ret = Db::name('attendance_record')->insert($rdata); if(!$ret){ \exception('操作失败'); } $dates = json_decode($info['content'],true); foreach ($dates as $k=>$v){ if($rdata['cate'] == 1 && $v['stime'] == $rdata['kq_time']){ $dates[$k]['ssign'] = $rdata['create_time']; }else if($rdata['cate'] == 2 && $v['etime'] == $rdata['kq_time']){ $dates[$k]['esign'] = $rdata['create_time']; } } $userClassId = Db::name('attendance_user_class')->where('id',$info['id'])->update(['content' => json_encode($dates)]); if(!$userClassId){ \exception('保存失败'); } Db::commit(); }catch (Exception $e){ trace($e->getMessage()); Db::rollback(); HelpHander::error('操作失败'.$e->getMessage()); } return true; } // 获取补卡记录 public function reissueList($userId,$orgId){ $reissue_day = config('reissue_day'); $start_time = date('Y-m-d',time() - $reissue_day * 86400); $end_time = date('Y-m-d'); $lists = Db::name('attendance_user_class') ->where('user_id',$userId) ->where('org_id',$orgId) ->where('day','>=',$start_time) ->where('day','<',$end_time) ->where('status',1) ->field('id,user_id,content') ->select(); $nlist = []; foreach ($lists as $k=>$v){ $dates = json_decode($v['content'],true); foreach ($dates as $kk=>$vv){ $record1 = Db::name('attendance_record') ->where('user_id',$v['user_id']) ->where('user_class_id',$v['id']) ->where('effective',1) ->where('kq_time',$vv['stime']) ->find(); if(!$record1){ $nlist[] = [ 'id' => $vv['stime'], 'title' => '上班:'.$vv['stime'] ]; } $record2 = Db::name('attendance_record') ->where('user_id',$v['user_id']) ->where('user_class_id',$v['id']) ->where('effective',1) ->where('kq_time',$vv['etime']) ->find(); if(!$record2){ $nlist[] = [ 'id' => $vv['etime'], 'title' => '下班:'.$vv['etime'] ]; } } } return $nlist; } // 生成某天未打卡人员固定班制的记录 public function attendanceReissueFixed($day){ $nday = date('Y-m-d',strtotime($day) + 24*60*60); // 下一天 // 已参与考勤人员 $userIds2 = Db::name('attendance_user_class') ->where('day',$day) ->column('user_id'); // 查询固定班制考勤组 $groups = Db::name('attendance_group')->where('type',1)->where('del',0)->select(); $w = date('w',strtotime($day)); // 是周几 foreach ($groups as $key=>$val){ $content = json_decode($val['content'],true); $week = $content['week']; $classId = 0; foreach ($week as $k=>$v){ if($w == $v['week']){ $classId = empty($v['class_id'])?0:$v['class_id']; } } // 今日是否有必打卡特殊日 $sign = $content['sign']?$content['sign']:[]; foreach ($sign as $k=>$v){ if($day == $v['day']){ $classId = empty($v['class_id'])?0:$v['class_id']; } } // 今日是否有不必打卡特殊日 $unsign = $content['unsign']?$content['unsign']:[]; foreach ($unsign as $k=>$v){ if($day == $v['day']){ $classId = 0; } } if($classId <= 0){ continue; } $map[] = ['a.group_id','=',$val['id']]; if($userIds2){ $map[] = ['a.user_id','not in',$userIds2]; } $map[] = ['b.enable','=',1]; $map[] = ['b.del','=',0]; $map[] = ['c.is_working','in',[0,1,2]]; $uids = Db::name('attendance_group_user') ->alias('a') ->join('user b','b.id = a.user_id') ->join('user_info c','c.user_id = a.user_id') ->where($map) ->column('a.user_id'); $class = Db::name('attendance_class')->where('id',$classId)->find(); if(!$uids || !$class){ continue; } $content = json_decode($class['content'],true); $dates = $content['dates']; $newdates = []; //[{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}] $next = 0; foreach ($dates as $k=>$v){ $newdates[] = [ "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00', "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00', "sstatus" => 0, "estatus" => 0, "ssign" => '', "esign" => '', ]; if($v['snext'] == 1||$v['enext'] == 1){ $next = 1; } } if($next == 0){ // 不跨天 foreach ($newdates as $k=>$v){ $newdates[$k]['sstatus'] = 1; $newdates[$k]['estatus'] = 1; } $status = 1; }else{ // 跨天 foreach ($newdates as $k=>$v){ if($v['stime'] >= $nday.' 00:00:00'){ $newdates[$k]['sstatus'] = 0; }else{ $newdates[$k]['sstatus'] = 1; } if($v['etime'] >= $nday.' 00:00:00'){ $newdates[$k]['estatus'] = 0; }else{ $newdates[$k]['estatus'] = 1; } } $status = 0; } foreach ($uids as $k=>$v){ Db::name('attendance_user_class')->insert([ 'org_id' => $class['org_id'], 'user_id' => $v, 'class_id' => $class['id'], 'group_id' => $val['id'], 'content' => json_encode($newdates), 'day' => $day, 'next' => $next, 'status' => $status, 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]); } } } // 生成某天未打卡人员排班制的记录 public function attendanceReissueClass($day){ $nday = date('Y-m-d',strtotime($day) + 24*60*60); // 下一天 // 已参与考勤人员 $userIds2 = Db::name('attendance_user_class') ->where('day',$day) ->column('user_id'); $map = []; $map[] = ['u.del','=',0]; $map[] = ['u.enable','=',1]; $map[] = ['g.del','=',0]; $map[] = ['ui.is_working','in',[0,1,2]]; $map[] = ['agc.day','=',$day]; if($userIds2){ $map[] = ['u.id','not in',$userIds2]; } $lists = Db::name('attendance_group_user') ->alias('agu') ->join('attendance_group_class agc','agu.group_id = agc.group_id') ->join('user u','u.id = agu.user_id') ->join('user_info ui','ui.user_id = agu.user_id') ->join('attendance_group g','g.id = agu.group_id') ->join('attendance_class c','c.id = agc.class_id') ->where($map) ->field('agu.group_id,agu.user_id,agu.org_id,agc.class_id,c.content,agc.day') ->select(); $lists = $lists?$lists:[]; foreach ($lists as $key=>$val){ $content = json_decode($val['content'],true); $dates = $content['dates']; $newdates = []; $next = 0; foreach ($dates as $k=>$v){ $newdates[] = [ "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00', "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00', "sstatus" => 0, "estatus" => 0, "ssign" => '', "esign" => '', ]; if($v['snext'] == 1||$v['enext'] == 1){ $next = 1; } } if($next == 0){ // 不跨天 foreach ($newdates as $k=>$v){ $newdates[$k]['sstatus'] = 1; $newdates[$k]['estatus'] = 1; } $status = 1; }else{ // 跨天 foreach ($newdates as $k=>$v){ if($v['stime'] >= $day.' 00:00:00'){ $newdates[$k]['sstatus'] = 0; }else{ $newdates[$k]['sstatus'] = 1; } if($v['etime'] >= $day.' 00:00:00'){ $newdates[$k]['estatus'] = 0; }else{ $newdates[$k]['estatus'] = 1; } } $status = 0; } Db::name('attendance_user_class')->insert([ 'org_id' => $val['org_id'], 'user_id' => $val['user_id'], 'class_id' => $val['class_id'], 'group_id' => $val['group_id'], 'content' => json_encode($newdates), 'day' => $day, 'next' => $next, 'status' => $status, 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]); } } }