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.AttRule; import com.cloud.attendance.model.PersonForEs; import com.cloud.attendance.service.QueryEsService; import com.cloud.attendance.service.TokenService; 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.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.text.SimpleDateFormat; import java.util.*; @Service @Slf4j public class QueryEsServiceImpl implements QueryEsService { private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); @Autowired private RestTemplate restTemplate; @Autowired private EnumStr enumStr; @Autowired private TokenService tokenService; @Autowired private AttRuleDao attRuleDao; @Autowired private UserService userService; @Autowired private AttDayDao attDayDao; @Override public List queryAttRecordBySecond(){ List lists = new ArrayList(); HttpHeaders headers = new HttpHeaders(); String startTime = sdf.format(System.currentTimeMillis()-3000); String endTime = sdf.format(System.currentTimeMillis()-2000); String querySecondRecord = "{\"query\":{\"range\":{\""+EnumStr.picDateField+"\":{\"gte\":\""+startTime+"\",\"lt\":\""+endTime+"\"}}}}"; MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity(querySecondRecord, headers); ResponseEntity responseEntity = restTemplate.postForEntity("http://" + HttpClient.getHOSTNAME() + ":" + HttpClient.getHTTP_PORT() + "/cananaserman/_search", formEntity, JSONObject.class); if (!responseEntity.getStatusCode().is2xxSuccessful()){ // 报错 非200状态 throw new RuntimeException("es 查询秒级数据 返回失败!~"); }else { JSONObject resp = responseEntity.getBody(); JSONArray attRecords = resp.getJSONObject("hits").getJSONArray("hits"); for (Object attRecord : attRecords) { JSONObject source = ((JSONObject) attRecord).getJSONObject("_source"); // 获取 personId 组合数据 String pid = source.getString("pid"); // 直接查询数据库 // Map person= attDayDao.getPersonInfoById(pid); // 调用人员接口 Map person = userService.getPersonInfoById(pid); if (person!=null) { String showType = "其他"; if (EnumStr.TEACHER_SQL.equals(person.get("type"))){ showType = "教师"; }else if (EnumStr.STUDENT_SQL.equals(person.get("type"))){ showType = "学生"; } source.put("name",person.get("name")); source.put("identity",showType); source.put("photo",person.get("photos")); }else { source.put("identity",null); source.put("photo",null); source.put("name",null); } source.put(EnumStr.picDateShow,source.getString(EnumStr.picDateField)); // 考勤日期 source.put(EnumStr.snapPicShow,source.getString(EnumStr.perPicField)); // 抓拍图片 source.put(EnumStr.devIdShow,source.getString(EnumStr.devIdField)); // 设备IDID source.put(EnumStr.devNameShow,source.getString(EnumStr.devNameField)); // 设备名称 removeSource( source); // 伤处多余字段 lists.add(source); } } log.info(lists.size()+"条数据 es 定时发送"+System.currentTimeMillis()); return lists; } /** * "_source": { * "pname": "李姝宁", * "pid": "1552", * "onlinetime": "2018-10-31 02:00:04", * "indeviceid": "ZJKQJ-VIDEO", * "indevicename": "主教学楼考勤机" * } */ // 搜索条件查询 全部记录 public Map queryAttRecord(String contentValue, String location, String identity, String gradeValue, String classValue, Boolean delFlag, List orgIds, String orderName, String sortDate, Date startTime, Date endTime, Integer page, Integer size){ Map retMap = new HashMap(); String starttime = sdf.format(startTime); String endtime = sdf.format(endTime); int from =0; if (page!=null && size !=null ){ from = (page - 1) * size ; }else{ from = 0 ; size = 20; } retMap.put("total",0);retMap.put("size",size); // 设置 初始值 String personids = ""; // 查询条件满足的人员// (2018080601) or (2018080603) or (2018080604) String contentQuery = ""; String persinIdQuery = ""; List lists = new ArrayList(); // 存储返回数据 /* if (EnumStr.STUDENT.equalsIgnoreCase(identity)){ identity = EnumStr.STUDENT_SQL; }else if (EnumStr.TEACHER.equalsIgnoreCase(identity)){ identity = EnumStr.TEACHER_SQL; }else */ if (StringUtils.isBlank(identity)){ identity = null; } // 添加权限 LoginAppUser appUser = tokenService.currentUser(); Long orgId = appUser.getOrgId(); if (StringUtils.isBlank(gradeValue)){ Integer officeId = appUser.getOfficeId(); gradeValue = officeId.toString(); } // 摄像机范围 AttRule attRule = attRuleDao.selectAttRule(); String deviceIds = null; if (attRule != null) deviceIds = attRule.getDeviceIds(); String reqIds = null; if (!StringUtils.isBlank(deviceIds)){ reqIds = JSONArray.toJSONString(deviceIds.split(",")); }else { retMap.put("esAttList",new ArrayList<>()); return retMap; } // 调用 sql 直接查询人员数据 // List idList = attDayDao.queryPersonByContent(contentValue, gradeValue, classValue, identity, null); // // 调用 人员接口查询人员数据 List idList = userService.queryPersonByContent(contentValue,gradeValue,classValue,identity,null,delFlag,orgIds); String join = StringUtils.join(idList, ")or("); if (idList.size()>0){ personids = "("+ join +")"; persinIdQuery = ",{\"query_string\":{\"default_field\":\""+EnumStr.personIdField+"\",\"query\":\""+personids+"\"}}"; }else{ retMap.put("esAttList",lists); return retMap; } if (location !=null ){ // 处理 indevicename 字段为keyword则不能模糊查询 设为 text 则可以执行下列 // String location ="("+ String.join(")and(", location.split(""))+")"; // 2018-12-04 改为 位置 contentQuery = ",{\"query_string\":{\"default_field\":\""+EnumStr.devAddressField+"\",\"query\":\""+location+"\"}}"; } // 摄像机 范围条件添加 wp 19-03-20 if (!StringUtils.isBlank(reqIds) ){ contentQuery += ",{\"terms\":{\""+EnumStr.VideoReqNum+"\":"+reqIds+"}}"; } if ("desc".equalsIgnoreCase(sortDate)){ sortDate = "desc"; }else { sortDate = "asc"; } // 排序 字段 处理 String ordername = EnumStr.picDateField; if(EnumStr.devNameShow.equalsIgnoreCase(orderName)){ ordername = EnumStr.devAddressField; } String queryAttRecordByPerson = "{\"query\":{\"bool\":{\"must\":[{\"range\":{\""+EnumStr.picDateField+"\":{\"gte\":" + "\""+starttime+"\",\"lte\":\""+endtime+"\"}}}"+contentQuery+persinIdQuery+"]," + "\"must_not\":[],\"should\":[]}},\"from\":"+from+",\"size\":"+size+",\"sort\":{\""+ordername +"\":{\"order\":\""+sortDate+"\"}},\"aggs\":{}}"; // 增加排序类型 log.info(queryAttRecordByPerson+"查询 json 语句"); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity(queryAttRecordByPerson, headers); 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 查询秒级数据 返回失败!~"); }else{ JSONObject resp = responseEntity.getBody(); JSONObject hits = resp.getJSONObject("hits"); Integer total = hits.getInteger("total"); JSONArray attRecords = hits.getJSONArray("hits"); Map personType = userService.queryPersonType(); for (Object attRecord : attRecords){ JSONObject source = ((JSONObject) attRecord).getJSONObject("_source"); // source.put("identity",identity); // 获取 personId 组合数据 String pid = source.getString(EnumStr.personIdField); //直接查询数据库 // Map person= attDayDao.getPersonInfoById(pid); // 调用人员接口 Map person = userService.getPersonInfoById(pid); if (person!=null){ String showType = "其他"; String pertype = (String) person.get("type"); if (EnumStr.TEACHER_SQL.equals(pertype)){ showType = "教师"; }else if(EnumStr.STUDENT_SQL.equals(pertype)){ showType = "学生"; }else{ showType = personType.get(pertype); if (showType == null) showType = "其他"+pertype; } source.put(EnumStr.idCardField,person.get("cardId")); source.put(EnumStr.perIdentityShow,showType); source.put(EnumStr.photoAddShow,person.get("photos")); // 人员 是否 已删除 wp 19-03-15 String name = (String) person.get("name"); String perDelFlag = (String) person.get("delFlag"); if ("1".equals(perDelFlag)){ name = name != null?(name+"(已删除)"):"(已删除)"; } source.put(EnumStr.pnameShow,name != null?name:""); }else { source.put(EnumStr.idCardField,""); source.put(EnumStr.pnameShow,""); source.put(EnumStr.perIdentityShow,null); source.put(EnumStr.photoAddShow,null); } source.put(EnumStr.personIdShow,source.getString(EnumStr.personIdField)); // pid source.put(EnumStr.picDateShow,source.getString(EnumStr.picDateField).substring(0,19)); // 考勤日期 source.put(EnumStr.snapPicShow,source.getString(EnumStr.perPicField)); // 抓拍图片 source.put(EnumStr.devIdShow,source.getString(EnumStr.devIdField)); // 设备IDID String devName = source.getString(EnumStr.devNameShow); source.put(EnumStr.devNameShow,source.getString(EnumStr.devAddressField)); //devNameField设备名称 devAddressField source.put(EnumStr.devAddressField,devName); removeSource( source); // 伤处多余字段 lists.add(source); } retMap.put("total",total); } retMap.put("esAttList",lists); return retMap; } // 单人 单天 记录 List public Map queryPersonById(String pid,Date startTime, Date endTime){ String starttime = sdfDate.format(startTime); String endtime = sdfDate.format(endTime); String persinIdQuery = ",{\"query_string\":{\"default_field\":\""+EnumStr.personIdField+"\",\"query\":\""+pid+"\"}}"; String queryAttRecordByPerson = "{\"query\":{\"bool\":{\"must\":[{\"range\":{\""+EnumStr.picDateField+"\":{\"gte\":" + "\""+starttime+"\",\"lte\":\""+endtime+"\"}}}"+persinIdQuery+"]," + "\"must_not\":[],\"should\":[]}},\"from\":0,\"size\":1000,\"sort\":[\""+EnumStr.picDateField+"\"],\"aggs\":{}}"; log.info(queryAttRecordByPerson+"查询 json 语句"); List lists = new ArrayList(); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity(queryAttRecordByPerson, headers); ResponseEntity responseEntity = restTemplate.postForEntity("http://" +enumStr.getEsHOSTNAME() + ":" +enumStr.getEsHTTP_PORT() + "/"+EnumStr.esIndexField+"/_search", formEntity, JSONObject.class); Map personMap = new HashMap(); if (!responseEntity.getStatusCode().is2xxSuccessful()){ // 报错 非200状态 throw new RuntimeException("es 查询秒级数据 返回失败!~"); }else { JSONObject resp = responseEntity.getBody(); JSONArray attRecords = resp.getJSONObject("hits").getJSONArray("hits"); //直接查询数据库 // Map person= attDayDao.getPersonInfoById(pid); // 调用人员接口 Map person = userService.getPersonInfoById(pid); if (person != null){ String showType = "其他"; if (EnumStr.TEACHER_SQL.equals(person.get("type"))){ showType = "教师"; }else if (EnumStr.STUDENT_SQL.equals(person.get("type"))){ showType = "学生"; } personMap.put(EnumStr.perIdentityShow,showType); personMap.put(EnumStr.idCardField,person.get("cardId")); personMap.put(EnumStr.photoAddShow,person.get("photos")); personMap.put(EnumStr.pnameShow,person.get("name")); }else { personMap.put(EnumStr.perIdentityShow,""); personMap.put(EnumStr.photoAddShow,null); personMap.put(EnumStr.pnameShow,null); } for (Object attRecord : attRecords){ JSONObject source = ((JSONObject) attRecord).getJSONObject("_source"); // source.put("Snapshotpath",source.getString("Snapshotpath")); source.put(EnumStr.personIdShow,source.getString(EnumStr.personIdField)); // pid source.put(EnumStr.picDateShow,source.getString(EnumStr.picDateField).substring(0,19)); // 考勤日期 source.put(EnumStr.snapPicShow,source.getString(EnumStr.perPicField)); // 抓拍图片 source.put(EnumStr.devIdShow,source.getString(EnumStr.devIdField)); // 设备IDID source.put(EnumStr.devNameShow,source.getString(EnumStr.devAddressField)); // devNameField设备名称 devAddressField removeSource( source); // 伤处多余字段 lists.add(source); } personMap.put("dayList",lists); } return personMap; } private void removeSource(JSONObject source){ // "Age""BaseName""BeautyLevel""ChannlId":"FaceFeature""Gender": source.remove("Age"); source.remove("BaseName"); source.remove("BeautyLevel"); source.remove("ChannlId"); source.remove("FaceFeature");source.remove("Gender"); // "Id":"Race":"SimleLevel":"content":"idcard":"indeviceid":"indevicename": source.remove("Id"); source.remove("Race"); source.remove("SimleLevel"); source.remove("content"); //source.remove("idcard"); // "isDelete":"likeDate":"likePer":"personId":"personIsHub":"personPicUrl" source.remove("isDelete"); source.remove("likeDate"); source.remove("likePer"); source.remove("personIsHub"); // :"picAddress":"picDate":"picLocalUrl":"picMaxUrl":"picName": // source.remove("picAddress"); source.remove("picDate"); source.remove("picLocalUrl"); source.remove("picMaxUrl"); source.remove("picName"); // "picSmUrl":"viType":"videoIp":"videoNum":"videoReqNum": source.remove("videoIp"); source.remove("videoNum"); /* source.remove("videoReqNum");*/ } // 从es 查询所有人员 EnumStr.picDateField public List queryPersonIdFromEs(){ String queryAttRecordByPerson = "{\"size\":0,\"aggs\":{\""+EnumStr.personIdShow+"\":{\"terms\":{\"field\":\""+EnumStr.personIdField+"\"}},"+ "\"aggs\":{\"terms\":{\"size\":10000,\"field\":\""+EnumStr.personIdField+"\"},"+ "\"aggs\":{\"top_sales_hits\":{\"top_hits\":{\"_source\":{\"includes\":[\""+EnumStr.personIdField+"\",\"" +EnumStr.personUrlField+"\",\""+EnumStr.idCardField+"\"]},\"size\":1}}}}}}"; log.info(queryAttRecordByPerson+"查询 json 语句"); List listPer = new ArrayList(); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity(queryAttRecordByPerson, headers); ResponseEntity responseEntity = restTemplate.postForEntity("http://" +enumStr.getEsHOSTNAME() + ":" +enumStr.getEsHTTP_PORT() + "/"+EnumStr.esIndexField+"/_search", formEntity, JSONObject.class); Map personMap = new HashMap(); if (!responseEntity.getStatusCode().is2xxSuccessful()){ // 报错 非200状态 throw new RuntimeException("es 查询 人员数据 返回失败!~"); }else { JSONObject resp = responseEntity.getBody(); JSONArray perList = resp.getJSONObject("aggregations") .getJSONObject("aggs") .getJSONArray("buckets"); // 遍历加人 int times = 0; Integer[] is = {133,134,135,136,137,138,139,147,148,152}; // 年级班级列表 int il = is.length; for (Object perSource : perList){ PersonForEs perEs = new PersonForEs(); perEs.setCreateBy("es-add"); JSONArray hits = ((JSONObject) perSource).getJSONObject("top_sales_hits").getJSONObject("hits").getJSONArray("hits"); if (hits.size()>0){ JSONObject source = ((JSONObject)hits.get(0)).getJSONObject("_source"); log.info(source+"es 中人员情况"); if(source != null &&!"wait todo".equalsIgnoreCase(source.getString(EnumStr.personIdField))){ perEs.setPid(source.getString(EnumStr.personIdField)); perEs.setOrgId(1); // 11 北京林业大学附属小学 perEs.setOfficeId(is[times++%il]); // 12 五年级 13 三班 30 31 52 53 73 74 perEs.setName(source.getString(EnumStr.idCardField)); perEs.setGender((int)(Math.random() * 2 + 1)==1?"男":"女"); perEs.setPhotos(source.getString(EnumStr.personUrlField)); perEs.setType((int)(Math.random() * 2 + 1)==1?EnumStr.STUDENT_SQL:EnumStr.TEACHER_SQL); listPer.add(perEs); if (times>100)times=0; // 重置 } } } } return listPer; } }