AttendanceUserClass.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. namespace app\common\model;
  3. use app\hander\HelpHander;
  4. use think\Db;
  5. use think\Exception;
  6. use think\Model;
  7. class AttendanceUserClass extends Model
  8. {
  9. // 获取当前排班班次
  10. public function getCurGroup($userId)
  11. {
  12. $day = date('Y-m-d');
  13. $yday = date('Y-m-d', strtotime($day) - 1000);
  14. $info = Db::name('attendance_user_class')->where('user_id', $userId)->where('day', $day)->find();
  15. if ($info) { // 当日班次存在直接返回
  16. return $info;
  17. }
  18. // 查看当日是否排班
  19. $class = model('AttendanceGroupClass')->getClassByDay($userId);
  20. // 当日不存在,获取昨日未结束班次,看看昨日班次是否跨天
  21. $info = Db::name('attendance_user_class')->where('user_id', $userId)->where('status', 0)->where('next', 1)->where('day', $yday)->find();
  22. if ($info) {
  23. // 检查此跨天班次是否已结束
  24. if (!$class) { // 今天没有班次
  25. return $info; // 存在昨日跨天班次,直接返回
  26. }
  27. $content = json_decode($class['content'], true);
  28. $date = $content['dates'];
  29. $firstTime = strtotime(date('Y-m-d') . $date[0]['stime']);
  30. if ($firstTime - 2 * 60 <= time()) { // 打卡前2分钟,结束上个班次,开启本班次
  31. // 结束上个班次
  32. $ycontent = json_decode($info['content'], true);
  33. foreach ($ycontent as $k => $v) {
  34. $ycontent[$k]['sstatus'] = 1;
  35. $ycontent[$k]['estatus'] = 1;
  36. }
  37. $res = Db::name('attendance_user_class')->where('id', $info['id'])->update([
  38. 'content' => json_encode($ycontent),
  39. 'status' => 1,
  40. 'update_time' => date('Y-m-d H:i:s')
  41. ]);
  42. if (!$res) { // 状态修改失败,直接抛出错误,终止程序
  43. \exception('状态修改失败');
  44. }
  45. // 添加今日班次
  46. $ret = $this->saveGroupClass($userId, $class);
  47. return $ret;
  48. } else { // 昨天班次可继续打卡
  49. return $info;
  50. }
  51. } else { // 添加今日班次
  52. if (!$class) { // 今天没有班次
  53. return false;
  54. }
  55. $ret = $this->saveGroupClass($userId, $class);
  56. return $ret;
  57. }
  58. }
  59. public function saveGroupClass($userId,$class){
  60. $day = date('Y-m-d');
  61. $nday = date('Y-m-d',strtotime($day) + 86400);
  62. // 只添加记录,不牵扯打卡
  63. $content = json_decode($class['content'],true);
  64. $dates = $content['dates'];
  65. $newdates = []; //[{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}]
  66. $next = 0;
  67. foreach ($dates as $k=>$v){
  68. $newdates[] = [
  69. "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00',
  70. "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00',
  71. "sstatus" => 0,
  72. "estatus" => 0,
  73. "ssign" => "",
  74. "esign" => ""
  75. ];
  76. if($v['snext'] == 1||$v['enext'] == 1){
  77. $next = 1;
  78. }
  79. }
  80. $userData = [
  81. 'user_id' => $userId,
  82. 'group_id' => $class['group_id'],
  83. 'class_id' => $class['class_id'],
  84. 'org_id' => $class['org_id'],
  85. 'content' => json_encode($newdates),
  86. 'create_time' => date('Y-m-d H:i:s'),
  87. 'day' => $day,
  88. 'next' => $next,
  89. 'status' => 0,
  90. 'duration' => 0
  91. ];
  92. $userClassId = Db::name('attendance_user_class')->insertGetId($userData);
  93. if(!$userClassId){ // 添加失败,直接抛出错误,终止程序
  94. \exception('添加今日班次失败');
  95. }
  96. $userData['id'] = $userClassId;
  97. return $userData;
  98. }
  99. // 生成某天未打卡人员固定班制的记录
  100. public function attendanceReissueFixed($day){
  101. $nday = date('Y-m-d',strtotime($day) + 24*60*60); // 下一天
  102. // 已参与考勤人员
  103. $userIds2 = Db::name('attendance_user_class')
  104. ->where('day',$day)
  105. ->column('user_id');
  106. // 查询固定班制考勤组
  107. $groups = Db::name('attendance_group')->where('type',1)->where('del',0)->select();
  108. $w = date('w',strtotime($day)); // 是周几
  109. foreach ($groups as $key=>$val){
  110. $content = json_decode($val['content'],true);
  111. $week = $content['week'];
  112. $classId = 0;
  113. foreach ($week as $k=>$v){
  114. if($w == $v['week']){
  115. $classId = empty($v['class_id'])?0:$v['class_id'];
  116. }
  117. }
  118. // 今日是否有必打卡特殊日
  119. $sign = $content['sign']?$content['sign']:[];
  120. foreach ($sign as $k=>$v){
  121. if($day == $v['day']){
  122. $classId = empty($v['class_id'])?0:$v['class_id'];
  123. }
  124. }
  125. // 今日是否有不必打卡特殊日
  126. $unsign = $content['unsign']?$content['unsign']:[];
  127. foreach ($unsign as $k=>$v){
  128. if($day == $v['day']){
  129. $classId = 0;
  130. }
  131. }
  132. if($classId <= 0){
  133. continue;
  134. }
  135. $map = [];
  136. $map[] = ['group_id','=',$val['id']];
  137. if($userIds2){
  138. $map[] = ['user_id','not in',$userIds2];
  139. }
  140. $uids = Db::name('attendance_group_user')->where($map)->column('user_id');
  141. $class = Db::name('attendance_class')->where('id',$classId)->find();
  142. if(!$uids || !$class){
  143. continue;
  144. }
  145. $content = json_decode($class['content'],true);
  146. $dates = $content['dates'];
  147. $newdates = []; //[{"stime":"2021-03-22 08:00:00","etime":"2021-03-22 18:00:00","sstatus":0,"estatus":0,"ssign":"","esign":""}]
  148. $next = 0;
  149. foreach ($dates as $k=>$v){
  150. $newdates[] = [
  151. "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00',
  152. "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00',
  153. "sstatus" => 0,
  154. "estatus" => 0,
  155. "ssign" => '',
  156. "esign" => '',
  157. ];
  158. if($v['snext'] == 1||$v['enext'] == 1){
  159. $next = 1;
  160. }
  161. }
  162. if($next == 0){ // 不跨天
  163. foreach ($newdates as $k=>$v){
  164. $newdates[$k]['sstatus'] = 1;
  165. $newdates[$k]['estatus'] = 1;
  166. }
  167. $status = 1;
  168. }else{ // 跨天
  169. foreach ($newdates as $k=>$v){
  170. if($v['stime'] >= $nday.' 00:00:00'){
  171. $newdates[$k]['sstatus'] = 0;
  172. }else{
  173. $newdates[$k]['sstatus'] = 1;
  174. }
  175. if($v['etime'] >= $nday.' 00:00:00'){
  176. $newdates[$k]['estatus'] = 0;
  177. }else{
  178. $newdates[$k]['estatus'] = 1;
  179. }
  180. }
  181. $status = 0;
  182. }
  183. foreach ($uids as $k=>$v){
  184. Db::name('attendance_user_class')->insert([
  185. 'org_id' => $class['org_id'],
  186. 'user_id' => $v,
  187. 'class_id' => $class['id'],
  188. 'group_id' => $val['id'],
  189. 'content' => json_encode($newdates),
  190. 'day' => $day,
  191. 'next' => $next,
  192. 'status' => $status,
  193. 'create_time' => date('Y-m-d H:i:s'),
  194. 'update_time' => date('Y-m-d H:i:s')
  195. ]);
  196. }
  197. }
  198. }
  199. // 生成某天未打卡人员排班制的记录
  200. public function attendanceReissueClass($day){
  201. $nday = date('Y-m-d',strtotime($day) + 24*60*60); // 下一天
  202. // 已参与考勤人员
  203. $userIds2 = Db::name('attendance_user_class')
  204. ->where('day',$day)
  205. ->column('user_id');
  206. $map = [];
  207. $map[] = ['u.del','=',0];
  208. $map[] = ['u.enable','=',1];
  209. $map[] = ['g.del','=',0];
  210. $map[] = ['agc.day','=',$day];
  211. if($userIds2){
  212. $map[] = ['u.id','not in',$userIds2];
  213. }
  214. $lists = Db::name('attendance_group_user')
  215. ->alias('agu')
  216. ->join('attendance_group_class agc','agu.group_id = agc.group_id')
  217. ->join('user u','u.id = agu.user_id')
  218. ->join('attendance_group g','g.id = agu.group_id')
  219. ->join('attendance_class c','c.id = agc.class_id')
  220. ->where($map)
  221. ->field('agu.group_id,agu.user_id,agu.org_id,agc.class_id,c.content,agc.day')
  222. ->select();
  223. $lists = $lists?$lists:[];
  224. foreach ($lists as $key=>$val){
  225. $content = json_decode($val['content'],true);
  226. $dates = $content['dates'];
  227. $newdates = [];
  228. $next = 0;
  229. foreach ($dates as $k=>$v){
  230. $newdates[] = [
  231. "stime" => $v['snext'] > 0?$nday .' '.$v['stime'].':00':$day.' '.$v['stime'].':00',
  232. "etime" => $v['enext'] > 0?$nday .' '.$v['etime'].':00':$day.' '.$v['etime'].':00',
  233. "sstatus" => 0,
  234. "estatus" => 0,
  235. "ssign" => '',
  236. "esign" => '',
  237. ];
  238. if($v['snext'] == 1||$v['enext'] == 1){
  239. $next = 1;
  240. }
  241. }
  242. if($next == 0){ // 不跨天
  243. foreach ($newdates as $k=>$v){
  244. $newdates[$k]['sstatus'] = 1;
  245. $newdates[$k]['estatus'] = 1;
  246. }
  247. $status = 1;
  248. }else{ // 跨天
  249. foreach ($newdates as $k=>$v){
  250. if($v['stime'] >= $day.' 00:00:00'){
  251. $newdates[$k]['sstatus'] = 0;
  252. }else{
  253. $newdates[$k]['sstatus'] = 1;
  254. }
  255. if($v['etime'] >= $day.' 00:00:00'){
  256. $newdates[$k]['estatus'] = 0;
  257. }else{
  258. $newdates[$k]['estatus'] = 1;
  259. }
  260. }
  261. $status = 0;
  262. }
  263. Db::name('attendance_user_class')->insert([
  264. 'org_id' => $val['org_id'],
  265. 'user_id' => $val['user_id'],
  266. 'class_id' => $val['class_id'],
  267. 'group_id' => $val['group_id'],
  268. 'content' => json_encode($newdates),
  269. 'day' => $day,
  270. 'next' => $next,
  271. 'status' => $status,
  272. 'create_time' => date('Y-m-d H:i:s'),
  273. 'update_time' => date('Y-m-d H:i:s')
  274. ]);
  275. }
  276. }
  277. }