AttendanceRecord.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. <?php
  2. namespace app\admin\controller;
  3. use think\Db;
  4. class AttendanceRecord extends Auth
  5. {
  6. public function index(){
  7. if(request()->isAjax()){
  8. //分页参数
  9. $length = input('rows',10,'intval'); //每页条数
  10. $page = input('page',1,'intval'); //第几页
  11. $star = ($page - 1) * $length; //分页开始位置
  12. //排序
  13. $sortRow = input('sidx','id','trim'); //排序列
  14. $sort = input('sord','desc','trim'); //排序方式
  15. $order = $sortRow.' '.$sort;
  16. $title = input('title','','trim');
  17. if($title){
  18. $map[] = ['u.real_name','like','%'.$title.'%'];
  19. }
  20. $start = input('start','','trim');
  21. if($start){
  22. $map[] = ['ar.create_time',',>=',$start.' 00:00:00'];
  23. }
  24. $end= input('end','','trim');
  25. if($end){
  26. $map[] = ['ar.create_time',',<=',$end.' 23:59:59'];
  27. }
  28. $map[] = ['u.del','=',0];
  29. $map[] = ['ar.org_id','=',cur_org_id()];
  30. $map= empty($map) ? true: $map;
  31. //数据查询
  32. $lists = db('attendance_record')
  33. ->alias('ar')
  34. ->field('u.real_name,ar.*')
  35. ->leftJoin('user u','u.id=ar.user_id')
  36. ->limit($star,$length)
  37. ->where($map)
  38. ->order(['ar.id'=>'desc'])
  39. ->select();
  40. foreach ($lists as $k=>$v){
  41. $lists[$k]['day'] = Db::name('attendance_user_class')->where('id',$v['user_class_id'])->value('day');
  42. $lists[$k]['group_name'] = Db::name('attendance_group')
  43. ->alias('ag')
  44. ->join('attendance_user_class auc', 'auc.group_id = ag.id')
  45. ->where('auc.id',$v['user_class_id'])
  46. ->value('ag.name');
  47. }
  48. //数据返回
  49. $totalCount = db('attendance_record')
  50. ->alias('ar')
  51. ->leftJoin('user u','u.id=ar.user_id')
  52. ->where($map)
  53. ->count();
  54. $totalPage = ceil($totalCount/$length);
  55. $result['page'] = $page;
  56. $result['total'] = $totalPage;
  57. $result['records'] = $totalCount;
  58. $result['rows'] = $lists;
  59. return json($result);
  60. }else{
  61. return $this->fetch();
  62. }
  63. }
  64. public function check(){
  65. if(request()->isAjax()){
  66. //分页参数
  67. $length = input('rows',10,'intval'); //每页条数
  68. $page = input('page',1,'intval'); //第几页
  69. $start = ($page - 1) * $length; //分页开始位置
  70. //排序
  71. $sortRow = input('sidx','id','trim'); //排序列
  72. $sort = input('sord','desc','trim'); //排序方式
  73. $order = $sortRow.' '.$sort;
  74. $title = input('title','','trim');
  75. if($title){
  76. $map[] = ['u.real_name','like','%'.$title.'%'];
  77. }
  78. $month = input('month','','trim');
  79. if($month){
  80. $map[] = ['auc.day','>=',$month.'-01'];
  81. $map[] = ['auc.day','<=',$month.'-31'];
  82. }else{
  83. $smonth= date('Y-m').'-01';
  84. $emonth = date('Y-m').'-31';
  85. $map[] = ['auc.day','>=',$smonth];
  86. $map[] = ['auc.day','<=',$emonth];
  87. }
  88. $map[] = ['u.del','=',0];
  89. $map[] = ['auc.org_id','=',cur_org_id()];
  90. $map= empty($map) ? true: $map;
  91. //数据查询
  92. $lists = db('attendance_user_class')
  93. ->alias('auc')
  94. ->field('u.real_name,auc.*')
  95. ->join('user u','u.id=auc.user_id')
  96. ->limit($start,$length)
  97. ->where($map)
  98. ->order(['auc.id'=>'desc'])
  99. ->select();
  100. foreach ($lists as $k=>$v){
  101. $record = db('attendance_record')
  102. ->where('user_class_id',$v['id'])
  103. ->order('create_time asc')
  104. ->select();
  105. $record = $record?$record:[];
  106. $lack = 0;
  107. $early = 0;
  108. $late = 0;
  109. foreach ($record as $kk=>$vv){
  110. if($vv['effective'] == 1&&$vv['status'] == 1){
  111. $late++;
  112. }else if($vv['effective'] == 1&&$vv['status'] == 2){
  113. $early++;
  114. }
  115. }
  116. $dates = json_decode($v['content'],true);
  117. $lists[$k]['content'] = $dates;
  118. foreach ($dates as $kk=>$vv){
  119. $snr = $enr = [];
  120. if($record){
  121. $f1 = 0;
  122. $f2 = 0;
  123. foreach ($record as $kkk=>$vvv){
  124. if($vvv['kq_time'] == $vv['stime']){
  125. $snr[] = $vvv;
  126. $f1 = 1;
  127. }
  128. if($vvv['kq_time'] == $vv['etime']){
  129. $enr[] = $vvv;
  130. $f2 = 1;
  131. }
  132. }
  133. if(!$f1){
  134. $lack++;
  135. }
  136. if(!$f2){
  137. $lack++;
  138. }
  139. }else{
  140. $lack += 2;
  141. }
  142. $dates[$kk]['slist'] = $snr;
  143. $dates[$kk]['elist'] = $enr;
  144. }
  145. $lists[$k]['lack'] = $lack; //缺卡次数
  146. $lists[$k]['early'] = $early; //早退
  147. $lists[$k]['late'] = $late; //迟到
  148. }
  149. //数据返回
  150. $totalCount = db('attendance_user_class')
  151. ->alias('auc')
  152. ->field('u.real_name,auc.*')
  153. ->join('user u','u.id=auc.user_id')
  154. ->where($map)
  155. ->count();
  156. $totalPage = ceil($totalCount/$length);
  157. $result['page'] = $page;
  158. $result['total'] = $totalPage;
  159. $result['records'] = $totalCount;
  160. $result['rows'] = $lists;
  161. return json($result);
  162. }else{
  163. $this->assign('month',date('Y-m'));
  164. return $this->fetch();
  165. }
  166. }
  167. public function checkDetails(){
  168. $id = input('id',0);
  169. if($id < 1){
  170. $this->error('参数错误');
  171. }
  172. $info = db('attendance_user_class')->where('id',$id)->find();
  173. $record = db('attendance_record')->where('user_class_id',$id)->order('create_time asc')->select();
  174. $record = $record?$record:[];
  175. $dates = json_decode($info['content'],true);
  176. foreach ($dates as $kk=>$vv){
  177. $snr = $enr = [];
  178. if($record){
  179. foreach ($record as $kkk=>$vvv){
  180. if($vvv['kq_time'] == $vv['stime']){
  181. $snr[] = $vvv;
  182. }
  183. if($vvv['kq_time'] == $vv['etime']){
  184. $enr[] = $vvv;
  185. }
  186. }
  187. }
  188. $dates[$kk]['slist'] = $snr;
  189. $dates[$kk]['elist'] = $enr;
  190. }
  191. $info['content'] = $dates;
  192. //获取今日请假记录
  193. $leave = db('attendance_leave')
  194. ->where('status',1)
  195. ->where('user_id',$info['user_id'])
  196. ->where('start_time','<=',$info['day'].' 23:59:59')
  197. ->where('end_time','>=',$info['day'].' 00:00:00')
  198. ->select();
  199. foreach ($leave as $k=>$v){
  200. if($v['leave_type'] == 1){
  201. $leave[$k]['leavetype_name'] = '事假';
  202. }
  203. if($v['leave_type'] == 2){
  204. $leave[$k]['leavetype_name'] = '病假';
  205. }
  206. if($v['leave_type'] == 3){
  207. $leave[$k]['leavetype_name'] = '年假';
  208. }
  209. if($v['leave_type'] == 4){
  210. $leave[$k]['leavetype_name'] = '婚假';
  211. }
  212. if($v['leave_type'] == 5){
  213. $leave[$k]['leavetype_name'] = '婚假';
  214. }
  215. if($v['leave_type'] == 6){
  216. $leave[$k]['leavetype_name'] = '丧假';
  217. }
  218. }
  219. $info['leave'] = $leave;
  220. $this->assign('info',$info);
  221. return $this->fetch();
  222. }
  223. // 改变打卡状态
  224. public function changeAttendance(){
  225. $data = [
  226. 'type' => input('type'),
  227. 'time' => input('time'),
  228. 'min' => input('min'),
  229. 'id' => input('id'),
  230. 'cate' => input('cate'),
  231. 'status' => input('status')
  232. ];
  233. if($data['type'] == 2 && $data['min'] <= 0){
  234. $this->error('分钟数不能为0');
  235. }
  236. if(!$data['time']){
  237. $this->error('参数错误1');
  238. }
  239. $info = db('attendance_user_class')->where('id',$data['id'])->find();
  240. if(!$info){
  241. $this->error('参数错误2');
  242. }
  243. if($data['cate'] == 1){ // 上班(正常上班/下班的记录是不可修改的)
  244. $ret = db('attendance_record')
  245. ->where('user_id',$info['user_id'])
  246. ->where('create_time',$data['time'])
  247. ->where('cate',1)
  248. ->where('effective',1)
  249. ->where('status',0)
  250. ->find();;
  251. if($ret){
  252. $this->error('上班打卡为正常状态,不能修改');
  253. }
  254. }else if($data['cate'] == 2){// 下班
  255. $ret = db('attendance_record')
  256. ->where('user_id',$info['user_id'])
  257. ->where('user_class_id',$data['id'])
  258. ->where('create_time',$data['time'])
  259. ->where('cate',2)
  260. ->where('effective',1)
  261. ->where('status',0)
  262. ->find();
  263. if($ret){
  264. $this->error('下班打卡为正常状态,不能修改');
  265. }
  266. }
  267. if($data['type'] == 1){
  268. $data['min'] = 0;
  269. }
  270. $signdate = $data['time'];
  271. $status = 0;
  272. $result = '管理员修改为:正常';
  273. if($data['cate'] == 1 && $data['type'] == 2){ //上班
  274. $signdate = date('Y-m-d H:i:s',strtotime($data['time']) + $data['min']*60);
  275. $status = 1;
  276. $result = '管理员修改为:迟到';
  277. }else if($data['cate'] == 2 && $data['type'] == 2){
  278. $signdate = date('Y-m-d H:i:s',strtotime($data['time']) - $data['min']*60);
  279. $status = 2;
  280. $result = '管理员修改为:早退';
  281. }
  282. Db::startTrans();
  283. try{
  284. db('attendance_record')
  285. ->where('user_class_id',$data['id'])
  286. ->where('user_id',$info['user_id'])
  287. ->where('kq_time',$data['time'])
  288. ->update(['effective' => 0,'result'=>"打卡无效:此记录已被更新"]);
  289. $rdata = [
  290. 'kq_time' => $data['time'],
  291. 'user_id' => $info['user_id'],
  292. 'org_id' => $info['org_id'],
  293. 'type' => 4,
  294. 'from' => '管理员修改',
  295. 'result' => $result,
  296. 'create_time' => $signdate,
  297. 'user_class_id' => $data['id'],
  298. 'effective' => 1,
  299. 'status' => $status,
  300. 'cate' => $data['cate'],
  301. 'duration' => $data['min']*60
  302. ];
  303. $add = db('attendance_record')->insert($rdata);
  304. if(!$add){
  305. exception('操作失败');
  306. }
  307. $dates = json_decode($info['content'],true);
  308. foreach ($dates as $k=>$v){
  309. if($rdata['cate'] == 1 && $v['stime'] == $rdata['kq_time']){
  310. $dates[$k]['ssign'] = $rdata['create_time'];
  311. }else if($rdata['cate'] == 2 && $v['etime'] == $rdata['kq_time']){
  312. $dates[$k]['esign'] = $rdata['create_time'];
  313. }
  314. }
  315. $save = db('attendance_user_class')->where('id',$info['id'])->update(['content' => json_encode($dates)]);
  316. if(!$save){
  317. exception('操作失败');
  318. }
  319. Db::commit();
  320. }catch (Exception $e){
  321. Db::rollback();
  322. $this->error('操作失败');
  323. }
  324. $this->success('操作成功');
  325. }
  326. public function results(){
  327. if(request()->isAjax()){
  328. //分页参数
  329. $length = input('rows',10,'intval'); //每页条数
  330. $page = input('page',1,'intval'); //第几页
  331. $start = ($page - 1) * $length; //分页开始位置
  332. //排序
  333. $sortRow = input('sidx','id','trim'); //排序列
  334. $sort = input('sord','desc','trim'); //排序方式
  335. $order = $sortRow.' '.$sort;
  336. $month = input('month','','trim');
  337. if($month){
  338. $map[] = ['auc.day','>=',$month.'-01'];
  339. $map[] = ['auc.day','<=',$month.'-31'];
  340. }else{
  341. $smonth= date('Y-m').'-01';
  342. $emonth = date('Y-m').'-31';
  343. $map[] = ['auc.day','>=',$smonth];
  344. $map[] = ['auc.day','<=',$emonth];
  345. }
  346. $start_time = $month.'-01';
  347. $end_time = $month.'-31';
  348. $map[] = ['u.del','=',0];
  349. $map[] = ['u.enable','=',1];
  350. $map[] = ['auc.org_id','=',cur_org_id()];
  351. $map= empty($map) ? true: $map;
  352. //数据查询
  353. $lists = db('attendance_user_class')
  354. ->alias('auc')
  355. ->field('auc.*,count(*) as days,u.real_name')
  356. ->join('user u','u.id=auc.user_id')
  357. ->limit($start,$length)
  358. ->where($map)
  359. ->order('auc.user_id asc')
  360. ->group('auc.user_id')
  361. ->select();
  362. foreach ($lists as $k=>$v){
  363. $duration = 0;
  364. $uclist = db('attendance_user_class')
  365. ->field('content')
  366. ->where('org_id',cur_org_id())
  367. ->where('day','>=',$start_time)
  368. ->where('day','<=',$end_time)
  369. ->where('user_id',$v['user_id'])
  370. ->select();
  371. foreach ($uclist as $key=>$val){
  372. $dates = json_decode($val['content'],true);
  373. foreach ($dates as $kk=>$vv){
  374. if(!empty($vv['ssgin']) && !empty($vv['esign'])){
  375. $duration += strtotime($vv['esign']) - strtotime($vv['ssgin']);
  376. }
  377. }
  378. }
  379. $lists[$k]['duration'] = round($duration/60);
  380. $work = db('attendance_record')
  381. ->alias('ar')
  382. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  383. ->field('auc.day')
  384. ->where('auc.org_id',cur_org_id())
  385. ->where('auc.day','>=',$start_time)
  386. ->where('auc.day','<=',$end_time)
  387. ->where('ar.user_id',$v['user_id'])
  388. ->group('auc.day')
  389. ->select();
  390. $lists[$k]['work'] = $work ? count($work): 0; // 出勤天数
  391. $bk = db('attendance_record')
  392. ->alias('ar')
  393. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  394. ->where('auc.org_id',cur_org_id())
  395. ->where('auc.day','>=',$start_time)
  396. ->where('auc.day','<=',$end_time)
  397. ->where('ar.type',2)
  398. ->where('ar.user_id',$v['user_id'])
  399. ->select();
  400. $lists[$k]['bk'] = $bk ? count($bk) : 0; // 补卡次数
  401. $late = db('attendance_record')
  402. ->alias('ar')
  403. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  404. ->where('auc.org_id',cur_org_id())
  405. ->where('auc.day','>=',$start_time)
  406. ->where('auc.day','<=',$end_time)
  407. ->where('ar.status',1)
  408. ->where('ar.effective',1)
  409. ->where('ar.user_id',$v['user_id'])
  410. ->select();
  411. $lists[$k]['late'] = $late ? count($late) :0; // 迟到次数
  412. $lated = db('attendance_record')
  413. ->alias('ar')
  414. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  415. ->where('auc.org_id',cur_org_id())
  416. ->where('auc.day','>=',$start_time)
  417. ->where('auc.day','<=',$end_time)
  418. ->where('ar.status',1)
  419. ->where('ar.effective',1)
  420. ->where('ar.user_id',$v['user_id'])
  421. ->sum('ar.duration');
  422. $lists[$k]['late_duration'] = $lated?round($lated['duration']/60):0; // 迟到时长
  423. $early = db('attendance_record')
  424. ->alias('ar')
  425. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  426. ->where('auc.org_id',cur_org_id())
  427. ->where('auc.day','>=',$start_time)
  428. ->where('auc.day','<=',$end_time)
  429. ->where('ar.status',2)
  430. ->where('ar.effective',1)
  431. ->where('ar.user_id',$v['user_id'])
  432. ->select();
  433. $lists[$k]['early'] = $early ? count($early) :0; // 早退次数
  434. $earlyd = db('attendance_record')
  435. ->alias('ar')
  436. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  437. ->where('auc.org_id',cur_org_id())
  438. ->where('auc.day','>=',$start_time)
  439. ->where('auc.day','<=',$end_time)
  440. ->where('ar.status',2)
  441. ->where('ar.effective',1)
  442. ->where('ar.user_id',$v['user_id'])
  443. ->sum('ar.duration');
  444. $lists[$k]['early_duration'] = $earlyd?round($earlyd['duration']/60):0; // 早退时长
  445. // 请假天数
  446. $leave = db('attendance_leave')
  447. ->where('user_id',$v['user_id'])
  448. ->where('status',1)
  449. ->where('start_time','<=',$end_time.' 23:59:59')
  450. ->where('end_time','>=',$start_time.' 00:00:00')
  451. ->sum('cur_days');
  452. $lists[$k]['leave'] = $leave ? round($leave['cur_days'],1): 0; // 请假天数
  453. }
  454. //数据返回
  455. $totalCount = db('attendance_user_class')
  456. ->alias('auc')
  457. ->field('auc.*,count(*) as days,u.real_name')
  458. ->join('user u','u.id=auc.user_id')
  459. ->where($map)
  460. ->count();
  461. $totalPage = ceil($totalCount/$length);
  462. $result['page'] = $page;
  463. $result['total'] = $totalPage;
  464. $result['records'] = $totalCount;
  465. $result['rows'] = $lists;
  466. return json($result);
  467. }else{
  468. $this->assign('month',date('Y-m'));
  469. return $this->fetch();
  470. }
  471. }
  472. //excel导出
  473. public function export() {
  474. $month = input('month','','trim');
  475. include_once env('root_path').'/extend/phpexcel/Classes/PHPExcel.php';
  476. if (request()->isGet()) {
  477. $start_time = $month.'-01';
  478. $end_time = $month.'-31';
  479. $map[] = ['u.del','=',0];
  480. $map[] = ['u.enable','=',1];
  481. $map[] = ['auc.org_id','=',cur_org_id()];
  482. $map= empty($map) ? true: $map;
  483. //数据查询
  484. $lists = db('attendance_user_class')
  485. ->alias('auc')
  486. ->field('auc.*,count(*) as days,u.real_name')
  487. ->join('user u','u.id=auc.user_id')
  488. ->where($map)
  489. ->order('auc.user_id asc')
  490. ->group('auc.user_id')
  491. ->select();
  492. foreach ($lists as $k=>$v){
  493. $duration = 0;
  494. $uclist = db('attendance_user_class')
  495. ->field('content')
  496. ->where('org_id',cur_org_id())
  497. ->where('day','>=',$start_time)
  498. ->where('day','<=',$end_time)
  499. ->where('user_id',$v['user_id'])
  500. ->select();
  501. foreach ($uclist as $key=>$val){
  502. $dates = json_decode($val['content'],true);
  503. foreach ($dates as $kk=>$vv){
  504. if(!empty($vv['ssgin']) && !empty($vv['esign'])){
  505. $duration += strtotime($vv['esign']) - strtotime($vv['ssgin']);
  506. }
  507. }
  508. }
  509. $lists[$k]['duration'] = round($duration/60);
  510. $work = db('attendance_record')
  511. ->alias('ar')
  512. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  513. ->field('auc.day')
  514. ->where('auc.org_id',cur_org_id())
  515. ->where('auc.day','>=',$start_time)
  516. ->where('auc.day','<=',$end_time)
  517. ->where('ar.user_id',$v['user_id'])
  518. ->group('auc.day')
  519. ->select();
  520. $lists[$k]['work'] = $work ? count($work): 0; // 出勤天数
  521. $bk = db('attendance_record')
  522. ->alias('ar')
  523. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  524. ->where('auc.org_id',cur_org_id())
  525. ->where('auc.day','>=',$start_time)
  526. ->where('auc.day','<=',$end_time)
  527. ->where('ar.type',2)
  528. ->where('ar.user_id',$v['user_id'])
  529. ->select();
  530. $lists[$k]['bk'] = $bk ? count($bk) : 0; // 补卡次数
  531. $late = db('attendance_record')
  532. ->alias('ar')
  533. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  534. ->where('auc.org_id',cur_org_id())
  535. ->where('auc.day','>=',$start_time)
  536. ->where('auc.day','<=',$end_time)
  537. ->where('ar.status',1)
  538. ->where('ar.effective',1)
  539. ->where('ar.user_id',$v['user_id'])
  540. ->select();
  541. $lists[$k]['late'] = $late ? count($late) :0; // 迟到次数
  542. $lated = db('attendance_record')
  543. ->alias('ar')
  544. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  545. ->where('auc.org_id',cur_org_id())
  546. ->where('auc.day','>=',$start_time)
  547. ->where('auc.day','<=',$end_time)
  548. ->where('ar.status',1)
  549. ->where('ar.effective',1)
  550. ->where('ar.user_id',$v['user_id'])
  551. ->sum('ar.duration');
  552. $lists[$k]['late_duration'] = $lated?round($lated['duration']/60):0; // 迟到时长
  553. $early = db('attendance_record')
  554. ->alias('ar')
  555. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  556. ->where('auc.org_id',cur_org_id())
  557. ->where('auc.day','>=',$start_time)
  558. ->where('auc.day','<=',$end_time)
  559. ->where('ar.status',2)
  560. ->where('ar.effective',1)
  561. ->where('ar.user_id',$v['user_id'])
  562. ->select();
  563. $lists[$k]['early'] = $early ? count($early) :0; // 早退次数
  564. $earlyd = db('attendance_record')
  565. ->alias('ar')
  566. ->join('attendance_user_class auc','ar.user_class_id = auc.id')
  567. ->where('auc.org_id',cur_org_id())
  568. ->where('auc.day','>=',$start_time)
  569. ->where('auc.day','<=',$end_time)
  570. ->where('ar.status',2)
  571. ->where('ar.effective',1)
  572. ->where('ar.user_id',$v['user_id'])
  573. ->sum('ar.duration');
  574. $lists[$k]['early_duration'] = $earlyd?round($earlyd['duration']/60):0; // 早退时长
  575. // 请假天数
  576. $leave = db('attendance_leave')
  577. ->where('user_id',$v['user_id'])
  578. ->where('status',1)
  579. ->where('start_time','<=',$end_time.' 23:59:59')
  580. ->where('end_time','>=',$start_time.' 00:00:00')
  581. ->sum('cur_days');
  582. $lists[$k]['leave'] = $leave ? round($leave['cur_days'],1): 0; // 请假天数
  583. }
  584. //实例化PHPExcel类
  585. $objPHPExcel =new \PHPExcel();
  586. //激活当前的sheet表
  587. $objPHPExcel->setActiveSheetIndex(0);
  588. //设置表格头(即excel表格的第一行)
  589. $objPHPExcel->setActiveSheetIndex(0)
  590. ->setCellValue('A1', '姓名')
  591. ->setCellValue('B1', '应出勤天数')
  592. ->setCellValue('C1', '出勤天数')
  593. ->setCellValue('D1', '工作时长')
  594. ->setCellValue('E1', '迟到次数')
  595. ->setCellValue('F1', '迟到时长')
  596. ->setCellValue('G1', '早退次数')
  597. ->setCellValue('H1', '早退时长')
  598. ->setCellValue('I1', '补卡次数')
  599. ->setCellValue('J1', '请假');
  600. // 设置表格头水平居中
  601. $objPHPExcel->setActiveSheetIndex(0)->getStyle('A1')->getAlignment()
  602. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  603. $objPHPExcel->setActiveSheetIndex(0)->getStyle('B1')->getAlignment()
  604. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  605. $objPHPExcel->setActiveSheetIndex(0)->getStyle('C1')->getAlignment()
  606. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  607. $objPHPExcel->setActiveSheetIndex(0)->getStyle('D1')->getAlignment()
  608. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  609. $objPHPExcel->setActiveSheetIndex(0)->getStyle('E1')->getAlignment()
  610. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  611. $objPHPExcel->setActiveSheetIndex(0)->getStyle('F1')->getAlignment()
  612. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  613. $objPHPExcel->setActiveSheetIndex(0)->getStyle('G1')->getAlignment()
  614. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  615. $objPHPExcel->setActiveSheetIndex(0)->getStyle('H1')->getAlignment()
  616. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  617. $objPHPExcel->setActiveSheetIndex(0)->getStyle('I1')->getAlignment()
  618. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  619. $objPHPExcel->setActiveSheetIndex(0)->getStyle('J1')->getAlignment()
  620. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  621. //设置列水平居中
  622. $objPHPExcel->setActiveSheetIndex(0)->getStyle('A')->getAlignment()
  623. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  624. $objPHPExcel->setActiveSheetIndex(0)->getStyle('B')->getAlignment()
  625. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  626. $objPHPExcel->setActiveSheetIndex(0)->getStyle('C')->getAlignment()
  627. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  628. $objPHPExcel->setActiveSheetIndex(0)->getStyle('D')->getAlignment()
  629. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  630. $objPHPExcel->setActiveSheetIndex(0)->getStyle('E')->getAlignment()
  631. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  632. $objPHPExcel->setActiveSheetIndex(0)->getStyle('F')->getAlignment()
  633. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  634. $objPHPExcel->setActiveSheetIndex(0)->getStyle('G')->getAlignment()
  635. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  636. $objPHPExcel->setActiveSheetIndex(0)->getStyle('H')->getAlignment()
  637. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  638. $objPHPExcel->setActiveSheetIndex(0)->getStyle('I')->getAlignment()
  639. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  640. $objPHPExcel->setActiveSheetIndex(0)->getStyle('J')->getAlignment()
  641. ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  642. //设置单元格宽度
  643. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('A')->setWidth(30);
  644. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('B')->setWidth(30);
  645. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('C')->setWidth(30);
  646. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('D')->setWidth(30);
  647. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('E')->setWidth(30);
  648. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('F')->setWidth(30);
  649. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('G')->setWidth(30);
  650. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('H')->setWidth(30);
  651. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('I')->setWidth(30);
  652. $objPHPExcel->setActiveSheetIndex(0)->getColumnDimension('J')->setWidth(30);
  653. //循环刚取出来的数组,将数据逐一添加到excel表格。
  654. for ($i = 0; $i < count($lists); $i++) {
  655. $objPHPExcel->getActiveSheet()->setCellValue('A' . ($i + 2), $lists[$i]['real_name']);
  656. $objPHPExcel->getActiveSheet()->setCellValue('B' . ($i + 2), $lists[$i]['days']);
  657. $objPHPExcel->getActiveSheet()->setCellValue('C' . ($i + 2), $lists[$i]['work']);
  658. $objPHPExcel->getActiveSheet()->setCellValue('D' . ($i + 2), $lists[$i]['duration']);
  659. $objPHPExcel->getActiveSheet()->setCellValue('E' . ($i + 2), $lists[$i]['late']);
  660. $objPHPExcel->getActiveSheet()->setCellValue('F' . ($i + 2), $lists[$i]['late_duration']);
  661. $objPHPExcel->getActiveSheet()->setCellValue('G' . ($i + 2), $lists[$i]['early']);
  662. $objPHPExcel->getActiveSheet()->setCellValue('H' . ($i + 2), $lists[$i]['early_duration']);
  663. $objPHPExcel->getActiveSheet()->setCellValue('I' . ($i + 2), $lists[$i]['bk']);
  664. $objPHPExcel->getActiveSheet()->setCellValue('J' . ($i + 2), $lists[$i]['leave']);
  665. }
  666. //设置保存的Excel表格名称
  667. $filename = '考勤报表_' . date('YmdHis', time()) . '.xls';
  668. //设置当前激活的sheet表格名称
  669. $objPHPExcel->getActiveSheet()->setTitle('考勤报表');
  670. //设置浏览器窗口下载表格
  671. ob_end_clean();
  672. header("Content-Type: application/force-download");
  673. header("Content-Type: application/octet-stream");
  674. header("Content-Type: application/download");
  675. header('Content-Disposition:inline;filename="' . $filename);
  676. //生成excel文件
  677. $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
  678. //下载文件在浏览器窗口
  679. return $objWriter->save('php://output');
  680. }
  681. }
  682. }