where('id',$data['user_id'])->value('device_sn'); if(!$device){ HelpHander::error('未绑定设备号'); } if($device != $data['device_sn']){ HelpHander::error('该设备与绑定设备不一致'); } // TODO::检查地点距离 $ret = $this->sign($data['device_sn'],$data['user_id'],$data['signtime'],1,$data['lat'],$data['lng'],$data['address'],$data['remark']); if(!$ret){ HelpHander::error($this->error); } return true; } // 为跨天的需要加一个定时任务,使考勤组状态变更 public function sign($sn,$pin,$signdate,$type=3,$lat='',$lng='',$address='',$remark=''){ //先检查这个时间点是否已记录在系统内 $res = Db::name('attendance_record')->where('user_id',$pin)->where('create_time',$signdate)->find(); if($res){ // 已存在返回已处理 return true; } $curTime = date('Y-m-d H:i:s'); $signtime = strtotime($signdate); // 检查当前打开时间是否有效 checkValid $ret = Db::name('attendance_record') ->alias('ar') ->join('attendance_user_class auc','auc.id = ar.user_class_id') ->where('ar.user_id',$pin) ->where('auc.status',1) ->where('ar.create_time','>',$signdate) ->field('ar.*') ->find(); if($ret){ // 时间无效,则标记为已处理 return true; } Db::startTrans(); try{ //先检查今天是否已生成打卡记录,未生成打卡记录需要查询昨天的考勤是否有跨天情况,取出今天的排班情况 $info = model('AttendanceUserClass')->getCurGroup($pin); if($info) { // 获取当前的班次,没有班次,当做外勤打卡 // 检查支持的考勤类型 $cate = Db::name('attendance_group')->where('id',$info['group_id'])->value('cate'); if($type == 1){ // 手机打开 if(!$cate){ trace('不支持手机打卡'); Db::commit(); return true; }else{ $cates = explode(',',$cate); if(!in_array(1,$cates)){ trace('不支持手机打卡'); Db::commit(); return true; } } }else if($type == 3){ //考勤机打卡 if(!$cate){ trace('不支持考勤机打卡'); Db::commit(); return true; }else{ $cates = explode(',',$cate); if(!in_array(2,$cates)){ trace('不支持考勤机打卡'); Db::commit(); return true; } } } if($info['day'] == date('Y-m-d') && $info['day'] != date('Y-m-d',$signtime)){ // 昨天的时间,今天的班次,不能使用 Db::commit(); return true; } $dates = json_decode($info['content'], true); $records = Db::name('attendance_record')->where('user_class_id', $info['id'])->order('create_time asc')->select(); $records = $records ? $records : []; $nrecords = []; $flag = false; $ndata = [ 'kq_time' => '', 'user_id' => $pin, 'org_id' => $info['org_id'], 'type' => $type, 'lat' => $lat, 'lng' => $lng, 'address' => $address, 'from' => $sn, 'result' => '', 'create_time' => date('Y-m-d H:i:s',$signtime), 'add_time' => $curTime, 'user_class_id' => $info['id'], 'effective' => 0, 'status' => 0, 'cate' => 0, 'duration' => 0, 'remark'=>$remark, ]; foreach ($records as $k => $v) { if (!$flag && strtotime($v['create_time']) > $signtime) { $nrecords[] = $ndata; $flag = true; } $nrecords[] = $v; } if(!$flag){ // 为最大值时 $nrecords[] = $ndata; } if (!$nrecords) { $nrecords[] = $ndata; } $datecount = count($dates); if ($datecount == 1) { // 一天一个班次 foreach ($nrecords as $k => $v) { if ($k == 0) { // 上班 $nrecords[$k]['kq_time'] = $dates[0]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['sstatus'] = 1; $dates[0]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[0]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[0]['stime']); $nrecords[$k]['result'] = '迟到'; } } else { // 下班 $nrecords[$k]['kq_time'] = $dates[0]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['estatus'] = 1; $dates[0]['esign'] = $v['create_time']; //判断是否是最后一条 if ($k + 1 == count($nrecords)) { // 是 if (strtotime($v['create_time']) < strtotime($dates[0]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[0]['etime']) - strtotime($v['create_time']); } } else { // 否,无效记录 $nrecords[$k]['effective'] = 0; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '打卡无效:此记录已被更新'; } } } }else if($datecount == 2){ // 一天二个班次 foreach ($nrecords as $k => $v) { if ($k == 0) { // 1次上班 $nrecords[$k]['kq_time'] = $dates[0]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['sstatus'] = 1; $dates[0]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[0]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[0]['stime']); $nrecords[$k]['result'] = '迟到'; } } else if ($k == 1){ // 1次下班 $nrecords[$k]['kq_time'] = $dates[0]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['estatus'] = 1; $dates[0]['esign'] = $v['create_time']; if (strtotime($v['create_time']) < strtotime($dates[0]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[0]['etime']) - strtotime($v['create_time']); } } else if ($k == 2){ // 2次上班 $nrecords[$k]['kq_time'] = $dates[1]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[1]['sstatus'] = 1; $dates[1]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[1]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[1]['stime']); $nrecords[$k]['result'] = '迟到'; } } else { // 2次下班 $nrecords[$k]['kq_time'] = $dates[1]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[1]['estatus'] = 1; $dates[1]['esign'] = $v['create_time']; //判断是否是最后一条 if ($k + 1 == count($nrecords)) { // 是 if (strtotime($v['create_time']) < strtotime($dates[1]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[1]['etime']) - strtotime($v['create_time']); } } else { // 否,无效记录 $nrecords[$k]['effective'] = 0; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '打卡无效:此记录已被更新'; } } } }else if($datecount == 3){ // 一天三个班次 foreach ($nrecords as $k => $v) { if ($k == 0) { // 1次上班 $nrecords[$k]['kq_time'] = $dates[0]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['sstatus'] = 1; $dates[0]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[0]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[0]['stime']); $nrecords[$k]['result'] = '迟到'; } } else if ($k == 1){ // 1次下班 $nrecords[$k]['kq_time'] = $dates[0]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[0]['estatus'] = 1; $dates[0]['esign'] = $v['create_time']; if (strtotime($v['create_time']) < strtotime($dates[0]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[0]['etime']) - strtotime($v['create_time']); } } else if ($k == 2){ // 2次上班 $nrecords[$k]['kq_time'] = $dates[1]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[1]['sstatus'] = 1; $dates[1]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[1]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[1]['stime']); $nrecords[$k]['result'] = '迟到'; } } else if ($k == 3){ // 2次下班 $nrecords[$k]['kq_time'] = $dates[1]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[1]['estatus'] = 1; $dates[1]['esign'] = $v['create_time']; if (strtotime($v['create_time']) < strtotime($dates[1]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[1]['etime']) - strtotime($v['create_time']); } } else if ($k == 4){ // 3次上班 $nrecords[$k]['kq_time'] = $dates[2]['stime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 1; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[2]['sstatus'] = 1; $dates[2]['ssign'] = $v['create_time']; if (strtotime($v['create_time']) > strtotime($dates[2]['stime'])) { // 迟到 $nrecords[$k]['status'] = 1; $nrecords[$k]['duration'] = strtotime($v['create_time']) - strtotime($dates[2]['stime']); $nrecords[$k]['result'] = '迟到'; } } else { // 3次下班 $nrecords[$k]['kq_time'] = $dates[2]['etime']; $nrecords[$k]['effective'] = 1; $nrecords[$k]['cate'] = 2; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '正常'; $dates[2]['estatus'] = 1; $dates[2]['esign'] = $v['create_time']; //判断是否是最后一条 if ($k + 1 == count($nrecords)) { // 是 if (strtotime($v['create_time']) < strtotime($dates[2]['etime'])) { // 早退 $nrecords[$k]['result'] = '早退'; $nrecords[$k]['status'] = 2; $nrecords[$k]['duration'] = strtotime($dates[2]['etime']) - strtotime($v['create_time']); } } else { // 否,无效记录 $nrecords[$k]['effective'] = 0; $nrecords[$k]['status'] = 0; $nrecords[$k]['duration'] = 0; $nrecords[$k]['result'] = '打卡无效:此记录已被更新'; } } } } foreach ($nrecords as $k=>$v){ $v['update_time'] = date('Y-m-d H:i:s'); if(isset($v['id']) && $v['id'] > 0){ //修改记录 $ret = Db::name('attendance_record')->where('id',$v['id'])->update($v); }else{ // 新增记录 $ret = Db::name('attendance_record')->insert($v); } if(!$ret){ \exception('打卡失败'); } } $res = Db::name('attendance_user_class')->where('id',$info['id'])->update([ 'content' => json_encode($dates), 'update_time' => date('Y-m-d H:i:s') ]); if(!$res){ \exception('打卡失败'); } } else { // 外勤打卡 $org_id = Db::name('user') ->alias('u') ->join('user_roles ur','ur.user_id = u.id') ->join('roles r','r.id = ur.roles_id') ->where('u.id',$pin) ->where('r.type',3) ->value('r.org_id'); $rdata = [ 'user_id' => $pin, 'org_id' => $org_id?$org_id:0, 'type' => $type, 'lat' => $lat, 'lng' => $lng, 'address' => $address, 'from' => $sn, 'result' => '外勤', 'create_time' => date('Y-m-d H:i:s',$signtime), 'add_time' => date('Y-m-d H:i:s'), 'user_class_id' => 0, 'effective' => 1, 'status' => 0, 'cate' => 0, 'duration' => 0 ]; $ret = Db::name('attendance_record')->insert($rdata); if(!$ret){ \exception('打卡失败'); } } Db::commit(); }catch (Exception $e){ trace($e->getMessage()); $this->error = $e->getMessage(); Db::rollback(); return false; } return true; } function bundleDevice($userId,$deviceSn){ if(!$deviceSn){ HelpHander::error('参数错误'); } $user = Db::name('user')->where('id',$userId)->find(); if(!$user){ HelpHander::error('用户不存在'); } if($user['device_sn']){ HelpHander::error('该用户已绑定设备'); } $uinfo = Db::name('user')->where('device_sn',$deviceSn)->find(); if($uinfo){ HelpHander::error('该设备已绑定用户'); } $ret = Db::name('user')->where('id',$userId)->setField('device_sn',$deviceSn); if(!$ret){ HelpHander::error('操作失败'); } return true; } }