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<AttDay> 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<String> formEntity = new HttpEntity<String>(esJson, headers); // json 启动 赋值
|
ResponseEntity<JSONObject> 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<String,JSONObject> persons = userService.queryAllPersonId();
|
List<String> existPer = attDayDao.selectPersonByDate(new Date());
|
existPer.forEach(userId -> {
|
persons.remove(userId);
|
});
|
// 去除存在人员
|
Collection<JSONObject> valueCollection2 = persons.values();
|
List<Object> valueList= new ArrayList<Object>(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<PersonForEs> 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<JSONObject> 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 时间");
|
}
|
|
}
|