package com.cloud.attendance.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.cloud.attendance.dao.AttDayDao; import com.cloud.attendance.dao.AttRuleDao; import com.cloud.attendance.model.AttDay; import com.cloud.attendance.model.AttRule; import com.cloud.attendance.model.PersonForEs; import com.cloud.attendance.service.QueryEsService; import com.cloud.attendance.service.TokenService; //import com.cloud.attendance.util.HttpClient; import com.cloud.attendance.service.UserService; import com.cloud.attendance.utils.EnumStr; import com.cloud.attendance.utils.HttpClient; import com.cloud.model.sys.LoginAppUser; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j @Component @Configurable @EnableScheduling // 主要 3 个 定时任务 public class ScheduledDayData { @Autowired private AttDayDao attDayDao; @Autowired private AttRuleDao attRuleDao; @Autowired private RestTemplate restTemplate; @Autowired private EnumStr enumStr; @Autowired private UserService userService; private static final String terms = "{\"terms\":{\"videoReqNum\":reqList}}"; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); private SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss"); //每3分钟执行一次 @Scheduled(cron = "0 0/3 1-22 * * *") public void reportCurrentByCron(){ // 调用 http es 接口 查询 数据 ArrayList attDays = new ArrayList<>(); // signDate,inTime ,outTime ,inDeviceId ,inDeviceName,outDeviceId ,outDeviceName ,isNotSign ,isLate ,isLeaveEarly, // isLeave ,isRepair, revJson ,updateBy HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); String esJson = HttpClient.getEsJson(); AttRule attRule = attRuleDao.selectAttRule(); // 获取考勤规则 if (attRule == null){ log.info("考勤规则暂无,考勤暂时做不了"); // throw new RuntimeException("请先调整考勤规则,然后才会 依据规则 调整考勤数据。"); attRule = new AttRule(); attRule.setInTime("09:00"); attRule.setOutTime("18:00"); attRule.setInTimeMin(5); attRule.setOutTimeMin(5); } String deviceIds = attRule.getDeviceIds(); // 设备列表 起作用 if (StringUtils.isBlank(deviceIds)){ esJson = esJson.replace(",videoReqFilter",""); }else { String[] devIds = deviceIds.split(","); String reqList = terms.replace("reqList",JSONObject.toJSONString(devIds)); esJson = esJson.replace("videoReqFilter",reqList); } log.info("汇总语句:"+esJson); HttpEntity formEntity = new HttpEntity(esJson, headers); // json 启动 赋值 ResponseEntity responseEntity = restTemplate.postForEntity("http://" + enumStr.getEsHOSTNAME() + ":" + enumStr.getEsHTTP_PORT() + "/"+EnumStr.esIndexField+"/_search", formEntity, JSONObject.class); if (!responseEntity.getStatusCode().is2xxSuccessful()){ // 报错 非200状态 throw new RuntimeException("es json 返回失败!~"); }else { JSONObject resp = responseEntity.getBody(); // HttpClient.HttpPostWithJson("/cananaserman/_search", HttpClient.getEsJson()); // JSONObject resp = JSONObject.parseObject(esRtnJson); // 返回json // JSONObject signtimes = new Date(); // 签到 集合 JSONArray sources = resp.getJSONObject("aggregations").getJSONObject("aggs_bucket").getJSONArray("buckets"); // buckets 数据集合 try { Date signDate = new Date(); // 考勤日期 log.info(signDate+"signDate:考勤日期"); Date inTime = getInTimeMin(attRule,null); // 考勤迟到截止 Date outTime = getOutTimeMin(attRule,null); // 考勤早退截止 LoginAppUser loginAppUser = null; // tokenService.currentUser(); if (loginAppUser==null|| loginAppUser.getUsername()==null){ loginAppUser = new LoginAppUser();loginAppUser.setUsername("basic-wp"); } for (Object source : sources) { JSONObject jsonSource = (JSONObject) source; // AttDay attDay = new AttDay(); // personId attDay.setSignDate(signDate); // 签到日期 2018-10-30 只是在下方代码判定需要、、是否签到,为null,则迟到早退给定null attDay.preUpdate(loginAppUser); // 更新日期 // log.info(jsonSource+":source 每个人的每天记录汇总"); attDay.setEmployeeId (jsonSource.getString("key")); JSONArray inTimesource = jsonSource.getJSONObject("top_min_hits").getJSONObject("hits").getJSONArray("hits"); JSONObject _source = null; if (inTimesource.size()>0){ _source = ((JSONObject) inTimesource.get(0)).getJSONObject("_source"); // hits 中元素 _source attDay.setIsNotSign(0); attDay.setInTime(_source.getDate(EnumStr.picDateField)); // 切记时 getDate 不是 getSqlDate attDay.setInDeviceId(_source.getString(EnumStr.devIdField)); attDay.setInDeviceName(_source.getString(EnumStr.devAddressField)); // 11-30 设备名称 修改为 地址 }else{ attDay.setSignDate(null);} JSONArray outTimesource = jsonSource.getJSONObject("top_max_hits").getJSONObject("hits").getJSONArray("hits"); if (outTimesource.size()>0){ _source = ((JSONObject) outTimesource.get(0)).getJSONObject("_source"); // hits 中元素 _source attDay.setOutTime(_source.getDate(EnumStr.picDateField)); attDay.setOutDeviceId(_source.getString(EnumStr.devIdField)); attDay.setOutDeviceName(_source.getString(EnumStr.devAddressField)); // 11-30 devNameField 修改为 devAddressField }else{ attDay.setSignDate(null); } if (attDay.getSignDate() == null){ attDay.setSignDate(new Date()); attDay.setIsNotSign(1);attDay.setIsLate(null);attDay.setIsLeaveEarly(null); }else{ // 时间 比较 验证 迟到早退 attDay.setIsNotSign(0); // 0 已签 1 未签 if (inTime.after(attDay.getInTime())){ //迟到 0否 1是', attDay.setIsLate(0); }else{ attDay.setIsLate(1);} log.info(outTime.toString()+"--》outTime"+new Date()); log.info(outTime.before(new Date())+"确认状态信息"); if (outTime.before(new Date())){ // 如果 考勤 未到 迟到之前 不做记录 if (outTime.before(attDay.getOutTime())){ // 是否早退 0否 1是', attDay.setIsLeaveEarly(0); }else {attDay.setIsLeaveEarly(1); } } } // 考勤规则 如果是未启用 ,则 迟到和早退 置 0 为 否 if (attDay.getSignDate() != null && (attRule.getEnable() == null || attRule.getEnable()==0)){ attDay.setIsLate(0); attDay.setIsLeaveEarly(0); } attDays.add(attDay); } log.info(attDays.size()+"查询将修改人数"); String ids = ""; for (AttDay attDay : attDays) { ids += (","+attDay.getEmployeeId()); } int i = 0 ; if (attDays.size()>0){ i = attDayDao.updateByMorePerId(attDays);// 修改考勤记录 } log.info(i+"修改内容。。。"+"ids:"+ids); }catch (ParseException e){ e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } // 获取 迟到 截止时间 09:05:00 public Date getInTimeMin(AttRule attRule,Date mouthDate) throws ParseException { String inTime = attRule.getInTime(); if (inTime==null)inTime = "09:00:00"; String[] intimes = inTime.split(" "); inTime = intimes[intimes.length-1]; if (mouthDate == null){ mouthDate = new Date(); } if(!isTime(inTime)){ log.info(inTime+"inTime 验证09:00验证失败!~"); if (inTime.split(":").length==2){ inTime = inTime+":00"; } }else{ log.info(inTime+" 验证验证成功!~"); } long time = attRule.getInTimeMin()*60*1000;//5 分钟 Date beforeDate = new Date(sdfDate.parse(sdf.format(mouthDate)+" "+inTime).getTime() + time);//30分钟前的时间 log.info("本次考勤规则 判断迟到截止时间"+sdfDate.format(beforeDate)); return beforeDate; } // 获取 早退 截止时间 public Date getOutTimeMin(AttRule attRule,Date mouthDate) throws ParseException { String outTime = attRule.getOutTime(); if(outTime == null) outTime = "2019-03-07 18:30:00"; String[] outimes = outTime.split(" "); outTime = outimes[outimes.length-1]; if (mouthDate == null){ mouthDate = new Date(); } if(!isTime(outTime)){ log.info(outTime+" 验证验证失败!~"); if (outTime.split(":").length==2){ outTime = outTime+":00"; } }else { log.info(outTime + " 验证验证成功!~"); } long time = attRule.getOutTimeMin()*60*1000;//5 分钟 Date afterDate = new Date(sdfDate.parse(sdf.format(mouthDate)+" "+outTime).getTime() - time);//5分钟后的时间 log.info("本次考勤规则 判断早退截止时间"+sdfDate.format(afterDate )); return afterDate; } // 时间 验证 15:30:30 public static boolean isTime(String time){ Pattern p = Pattern.compile("((((0?[0-9])|([1][0-9])|([2][0-4]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"); return p.matcher(time).matches(); } //每天晚上十点30触发 创建 第二天 所有人员 的空表数据 @Scheduled(cron = "0 50 22 * * ?") public void reportTomByDay(){ System.out.println ("Scheduling Tasks Examples By Day: The time is now " + sdfTime.format (new Date ())); // orgid employeeid employeename createby remarks createdate可null /// 调用 人员项目的查询所有人员 // attDayDao.insertEmployData("basic-wp-quarz"); // nickname 正式数据库 人员使用 // 查询 所有人员 加入 考勤库 JSONArray persons = userService.queryAllPersonList(); attDayDao.insertMoreData(persons,new Date(new Date().getTime()+1000*60*60*24),null,null); } //每天5分钟触发 创建 当天 所有人员 的空表数据 @Scheduled(cron = "0 0/5 2-22 * * ?") public void reportCurrentByDay(){ System.out.println ("2小时触发创建当天所有人员 的空表数据: The time is now " + sdfTime.format (new Date ())); // orgid employeeid employeename createby remarks createdate可null /// 直接sql 查询所有人员 // attDayDao.startInsertEmployData("basic-wp-quarz",null); // nickname 正式数据库 人员使用 /// 调用 人员项目的查询所有人员 Map persons = userService.queryAllPersonId(); List existPer = attDayDao.selectPersonByDate(new Date()); existPer.forEach(userId -> { persons.remove(userId); }); // 去除存在人员 Collection valueCollection2 = persons.values(); List valueList= new ArrayList(valueCollection2);//map转list if (valueList .size() > 0){ attDayDao.insertMoreData(valueList,null,null,null); } } //从 es 查询人员 然后加入 数据库 的空表数据 ,人员查询可以后,注释掉====================以下不用看了 // @Scheduled(cron = "0 30 * * * ?") public void addEsPersonByDay(){ System.out.println ("从 es 查询人员 然后加入 数据库addEsPersonByDay Day: time is now " + sdfTime.format (new Date ())); // id; Integer orgId;Integer officeId; // name; gender; type; photos; /// 调用 人员项目的查询所有人员 List persons = queryEsService.queryPersonIdFromEs(); log.info(persons.size()+"人员将被加入person_es库中"); for (PersonForEs person : persons){ try { int i = attDayDao.insertEsPerson(person); log.info(i+"将被加入"+person); }catch (RuntimeException ex) { log.info("添加es人员异常:"+ex.getLocalizedMessage()); } } } //每2分钟执行一次 测试 // @Scheduled(cron = "0/5 42-50 * * * *") public void reportCurrentTest(){ // 经测试 可以 log.info( sdfTime.format (new Date ())+"时间"); } @Autowired QueryEsService queryEsService; //每3秒执行一次 给前台 推数据 // @Scheduled(cron = "0/1 * * * * *") public void reportEswebSocket() { List jsonObjects = queryEsService.queryAttRecordBySecond(); try { if (jsonObjects.size() > 0){ MyWebSocket.sendInfo( jsonObjects.toString()); } }catch (IOException e) { e.printStackTrace(); } log.info( sdfTime.format (new Date ())+"query es 时间"); } //每3秒执行一次 测试 是否可以传参数 --- 不可以 // @Scheduled(cron = "0/3 * * * * *") public void testParam() { log.info("--===--测试 是否可以接收参数"); log.info( sdfTime.format (new Date ())+"query es 时间"); } }