package com.xkrs.helper; import com.xkrs.dao.FirePointOrdinaryDao; import com.xkrs.dao.FirePointPreciseDao; import com.xkrs.model.bean.FirePointQueryResultBean; import com.xkrs.model.bean.VipTimeRangeBean; import com.xkrs.model.entity.FirePointOrdinaryEntity; import com.xkrs.model.entity.FirePointPreciseEntity; import com.xkrs.model.entity.SysUserEntity; import com.xkrs.model.vo.AllFirePointVo; import com.xkrs.utilsnew.DateTimeUtils; import com.xkrs.utilsnew.FirePointCodeUtils; import com.xkrs.utilsnew.FirePointConvertUtils; import com.xkrs.utilsnew.JsonUtils; import com.xkrs.utilsold.DateTimeUtil; import org.apache.hc.core5.util.TextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.persistence.criteria.Predicate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @Component public class FirePointQueryManager { public static Logger log = LoggerFactory.getLogger(FirePointQueryManager.class); @Resource private FirePointOrdinaryDao firePointOrdinaryDao; @Resource private FirePointPreciseDao firePointPreciseDao; /** * 查询火点播报(无token) * * @param limit 最大数量 */ public FirePointQueryResultBean queryFirePointBroadcast(Integer limit) { int size = (limit != null && limit > 0) ? limit : 10; PageRequest pageRequest = PageRequest.of(1, size, Sort.by(Sort.Direction.DESC, "satelliteTime")); List firePointList = firePointPreciseDao.findAll(pageRequest).getContent(); List resultList = new ArrayList<>(); for (FirePointPreciseEntity firePoint : firePointList) { resultList.add(FirePointConvertUtils.convert(firePoint)); } return new FirePointQueryResultBean(true, "", resultList, resultList.size()); } public FirePointQueryResultBean queryFirePointBelongToUser(SysUserEntity sysUserEntity, String userSubAreaCountyCode, String startTime, String endTime, String satelliteType, String landType) { String countyCode = ("管理员".equals(sysUserEntity.getAccountType())) ? null : sysUserEntity.getCountyCode(); String vipTimeRangeJson = sysUserEntity.getVipTimeRangeJson(); return queryFirePointBelongToUser(countyCode, vipTimeRangeJson, userSubAreaCountyCode, startTime, endTime, satelliteType, landType); } public FirePointQueryResultBean queryFirePointBelongToUser(String userCode, String vipTimeRangeJson, String userSubAreaCountyCode, String startTime, String endTime, String satelliteType, String landType) { String noRedundantUserCode = null; String userSubAreaCutCountyCode = null; final List mVipTimeRangeItemList = new ArrayList<>(); try { noRedundantUserCode = (TextUtils.isEmpty(userCode)) ? null : FirePointCodeUtils.getFormatCutCode(userCode); userSubAreaCutCountyCode = (TextUtils.isEmpty(userSubAreaCountyCode)) ? null : FirePointCodeUtils.getFormatCutCode(userSubAreaCountyCode); //如果用户的VIP时间范围数据是空,就返回失败 if (TextUtils.isEmpty(vipTimeRangeJson)) { return new FirePointQueryResultBean("User VipTimeRangeJson Error 1, vipTimeRangeJson = " + vipTimeRangeJson); } //反序列化用户的VIP时间范围,得到对象 VipTimeRangeBean vipTimeRangeBean = JsonUtils.deserialize(vipTimeRangeJson, VipTimeRangeBean.class); //用户注册时有初始VIP时间范围,反序列化失败或无数据,说明该用户的数据发生了异常,返回失败 if (vipTimeRangeBean == null || vipTimeRangeBean.getList() == null || vipTimeRangeBean.getList().size() == 0) { return new FirePointQueryResultBean("User VipTimeRangeJson Error 2, 已保存的VIP时间范围反序列化失败, vipTimeRangeJson = " + vipTimeRangeJson); } //得到由<开始时间 + 结束时间>组成的集合 List vipTimeRangeItemList = vipTimeRangeBean.getList(); for (VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItemA : vipTimeRangeItemList) { //校验用户VIP开始时间合法性 if (!DateTimeUtil.isValidDateTime(vipTimeRangeItemA.getStartTime())) { return new FirePointQueryResultBean("User VIP 开始时间格式不合法1, StartTime = " + vipTimeRangeItemA.getStartTime()); } //校验用户VIP结束时间合法性 if (!DateTimeUtil.isValidDateTime(vipTimeRangeItemA.getEndTime())) { return new FirePointQueryResultBean("User VIP 结束时间格式不合法2, EndTime = " + vipTimeRangeItemA.getEndTime()); } LocalDateTime userStartLocalDateTimeA = LocalDateTime.parse(vipTimeRangeItemA.getStartTime(), DateTimeUtils.DATE_TIME_FORMATTER_1); LocalDateTime userEndLocalDateTimeA = LocalDateTime.parse(vipTimeRangeItemA.getEndTime(), DateTimeUtils.DATE_TIME_FORMATTER_1); for (VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItemB : vipTimeRangeItemList) { if (vipTimeRangeItemA != vipTimeRangeItemB) { //校验用户VIP开始时间合法性 if (!DateTimeUtil.isValidDateTime(vipTimeRangeItemB.getStartTime())) { return new FirePointQueryResultBean("User VIP 开始时间格式不合法3, StartTime = " + vipTimeRangeItemB.getStartTime()); } //校验用户VIP结束时间合法性 if (!DateTimeUtil.isValidDateTime(vipTimeRangeItemB.getEndTime())) { return new FirePointQueryResultBean("User VIP 结束时间格式不合法4, EndTime = " + vipTimeRangeItemB.getEndTime()); } LocalDateTime userStartLocalDateTimeB = LocalDateTime.parse(vipTimeRangeItemB.getStartTime(), DateTimeUtils.DATE_TIME_FORMATTER_1); LocalDateTime userEndLocalDateTimeB = LocalDateTime.parse(vipTimeRangeItemB.getEndTime(), DateTimeUtils.DATE_TIME_FORMATTER_1); //校验用户VIP开始结束时间是否存在交叉现象 if (userStartLocalDateTimeB.isBefore(userStartLocalDateTimeA) && userEndLocalDateTimeB.isAfter(userStartLocalDateTimeA)) { return new FirePointQueryResultBean("User VIP 开始结束时间格式不合法5, 存在交叉现象"); } if (userStartLocalDateTimeB.isBefore(userEndLocalDateTimeA) && userEndLocalDateTimeB.isAfter(userEndLocalDateTimeA)) { return new FirePointQueryResultBean("User VIP 开始结束时间格式不合法6, 存在交叉现象"); } } } } mVipTimeRangeItemList.addAll(vipTimeRangeItemList); } catch (Exception e) { e.printStackTrace(); return new FirePointQueryResultBean(e.getMessage()); } return queryFirePointBelongToUser(noRedundantUserCode, mVipTimeRangeItemList, userSubAreaCutCountyCode, startTime, endTime, satelliteType, landType); } public FirePointQueryResultBean queryFirePointBelongToUser(String noRedundantUserCode, List vipTimeRangeItemList, String userSubAreaCutCountyCode, String startTime, String endTime, String satelliteType, String landType) { //VIP时间范围发生了异常,返回失败 if (vipTimeRangeItemList == null || vipTimeRangeItemList.size() == 0) { return new FirePointQueryResultBean("User VipTimeRangeJson Error 2, 已保存的VIP时间范围出现错误"); } //查询未审核的普通火点 Specification specificationOrdinary = (root, criteriaQuery, criteriaBuilder) -> { List predicateList = new ArrayList<>(); //非空判断 predicateList.add(criteriaBuilder.isNotNull(root.get("proCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("proName").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("cityCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("cityName").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("countyCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("countyName").as(String.class))); //添加区划编码的过滤 if (!TextUtils.isEmpty(noRedundantUserCode)) { predicateList.add(criteriaBuilder.like(root.get("townCode").as(String.class), noRedundantUserCode + "%")); } //添加子区域区划编码的过滤(比如查询火点的系统用户所属的区划是山东省,但是该用户目前只想查询青岛市的火点,那么noRedundantUserCode=山东省区划,userSubAreaCutCountyCode=青岛市区划) if (!TextUtils.isEmpty(userSubAreaCutCountyCode)) { predicateList.add(criteriaBuilder.like(root.get("townCode").as(String.class), userSubAreaCutCountyCode + "%")); } //开始时间查询条件 if (!TextUtils.isEmpty(startTime)) { LocalDateTime startTime1 = DateTimeUtils.stringToLocalDateTime(startTime); LocalDateTime startTime2 = LocalDateTime.of(startTime1.getYear(), startTime1.getMonth(), startTime1.getDayOfMonth(), 0, 0, 0, 0); String startTimeString = DateTimeUtils.localDateTimeToString(startTime2); predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("satelliteTime").as(String.class), startTimeString)); } //结束时间查询条件 if (!TextUtils.isEmpty(endTime)) { LocalDateTime endTime1 = DateTimeUtils.stringToLocalDateTime(endTime).plusDays(1); LocalDateTime endTime2 = LocalDateTime.of(endTime1.getYear(), endTime1.getMonth(), endTime1.getDayOfMonth(), 0, 0, 0, 0); String endTimeString = DateTimeUtils.localDateTimeToString(endTime2); predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("satelliteTime").as(String.class), endTimeString)); } //卫星类型查询条件 if (!TextUtils.isEmpty(satelliteType)) { predicateList.add(criteriaBuilder.equal(root.get("satelliteType").as(String.class), satelliteType)); } //地物类型查询条件 if (!TextUtils.isEmpty(landType)) { predicateList.add(criteriaBuilder.equal(root.get("landType").as(String.class), landType)); } for (VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItem : vipTimeRangeItemList) { String userStartTime = vipTimeRangeItem.getStartTime(); String userEndTime = vipTimeRangeItem.getEndTime(); //早于(不包含)VIP开始时间 Predicate beforeStartTimePredicate = criteriaBuilder.lessThan(root.get("satelliteTime").as(String.class), userStartTime); //晚于(不包含)VIP结束时间 Predicate afterEndTimePredicate = criteriaBuilder.greaterThan(root.get("satelliteTime").as(String.class), userEndTime); predicateList.add(criteriaBuilder.or(beforeStartTimePredicate, afterEndTimePredicate)); } return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()])); }; //未审核的普通火点列表 List firePointOrdinaryList = firePointOrdinaryDao.findAll(specificationOrdinary, Sort.by(Sort.Direction.DESC, "satelliteTime")); //查询审核通过的精准火点 Specification specificationPrecise = (root, criteriaQuery, criteriaBuilder) -> { List predicateList = new ArrayList<>(); //非空判断 predicateList.add(criteriaBuilder.isNotNull(root.get("proCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("proName").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("cityCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("cityName").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("countyCode").as(String.class))); predicateList.add(criteriaBuilder.isNotNull(root.get("countyName").as(String.class))); //添加区划编码的过滤 if (!TextUtils.isEmpty(noRedundantUserCode)) { predicateList.add(criteriaBuilder.like(root.get("townCode").as(String.class), noRedundantUserCode + "%")); } //添加子区域区划编码的过滤(比如查询火点的系统用户所属的区划是山东省,但是该用户目前只想查询青岛市的火点,那么noRedundantUserCode=山东省区划,userSubAreaCutCountyCode=青岛市区划) if (!TextUtils.isEmpty(userSubAreaCutCountyCode)) { predicateList.add(criteriaBuilder.like(root.get("townCode").as(String.class), userSubAreaCutCountyCode + "%")); } //开始时间查询条件 if (!TextUtils.isEmpty(startTime)) { LocalDateTime startTime1 = DateTimeUtils.stringToLocalDateTime(startTime); LocalDateTime startTime2 = LocalDateTime.of(startTime1.getYear(), startTime1.getMonth(), startTime1.getDayOfMonth(), 0, 0, 0, 0); String startTimeString = DateTimeUtils.localDateTimeToString(startTime2); predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("satelliteTime").as(String.class), startTimeString)); } //结束时间查询条件 if (!TextUtils.isEmpty(endTime)) { LocalDateTime endTime1 = DateTimeUtils.stringToLocalDateTime(endTime).plusDays(1); LocalDateTime endTime2 = LocalDateTime.of(endTime1.getYear(), endTime1.getMonth(), endTime1.getDayOfMonth(), 0, 0, 0, 0); String endTimeString = DateTimeUtils.localDateTimeToString(endTime2); predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("satelliteTime").as(String.class), endTimeString)); } //卫星类型查询条件 if (!TextUtils.isEmpty(satelliteType)) { predicateList.add(criteriaBuilder.equal(root.get("satelliteType").as(String.class), satelliteType)); } //地物类型查询条件 if (!TextUtils.isEmpty(landType)) { predicateList.add(criteriaBuilder.equal(root.get("landType").as(String.class), landType)); } List subPredicateList = new ArrayList<>(); for (VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItem : vipTimeRangeItemList) { String userStartTime = vipTimeRangeItem.getStartTime(); String userEndTime = vipTimeRangeItem.getEndTime(); //晚于(包含)VIP开始时间 Predicate beforeStartTimePredicate = criteriaBuilder.greaterThanOrEqualTo(root.get("satelliteTime").as(String.class), userStartTime); //早于(包含)VIP结束时间 Predicate afterEndTimePredicate = criteriaBuilder.lessThanOrEqualTo(root.get("satelliteTime").as(String.class), userEndTime); subPredicateList.add(criteriaBuilder.and(beforeStartTimePredicate, afterEndTimePredicate)); } if (subPredicateList.size() == 0) { } else if (subPredicateList.size() == 1) { predicateList.add(subPredicateList.get(0)); } else { Predicate orPredicate = null; for (int i = 1; i < subPredicateList.size(); i++) { if (i == 1) { orPredicate = criteriaBuilder.or(subPredicateList.get(0), subPredicateList.get(1)); } else { orPredicate = criteriaBuilder.or(orPredicate, subPredicateList.get(i)); } } predicateList.add(orPredicate); } return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()])); }; //审核通过的精准火点列表 List firePointPreciseList = firePointPreciseDao.findAll(specificationPrecise, Sort.by(Sort.Direction.DESC, "satelliteTime")); //将两种数据来源的火点合并到一起 List resultList = new ArrayList<>(); for (FirePointOrdinaryEntity firePointOrdinaryEntity : firePointOrdinaryList) { resultList.add(FirePointConvertUtils.convert(firePointOrdinaryEntity)); } for (FirePointPreciseEntity firePointPreciseEntity : firePointPreciseList) { resultList.add(FirePointConvertUtils.convert(firePointPreciseEntity)); } //对合并后的结果进行排序 List sortedResultList = resultList.stream().sorted(Comparator.comparing(AllFirePointVo::getSatelliteTime)).collect(Collectors.toList()); return new FirePointQueryResultBean(true, "", sortedResultList, sortedResultList.size()); // { // final String commonSql = "SELECT t.id AS id, t.fire_code AS fireCode, t.county_code AS countyCode, t.county_name AS countyName, t.satellite_time AS satelliteTime, t.longitude AS longitude, t.latitude AS latitude, t.satellite_type AS satelliteType, t.land_type AS landType, t.confidence AS confidence, t.fire_image AS fireImage, t.satellite_image AS satelliteImage, t.town_code AS townCode, t.town_name AS townName, t.add_time AS addTime, t.fire_point_address AS firePointAddress, t.remark AS remark"; // // StringBuilder ordinaryBuilder = new StringBuilder(commonSql); // ordinaryBuilder.append(" FROM fire_point_ordinary AS t"); // ordinaryBuilder.append(" WHERE (t.town_code LIKE '" + mNoRedundantUserCode + "%')"); // ordinaryBuilder.append(" AND ("); // for (int i = 0; i < mVipTimeRangeItemList.size(); i++) { // VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItem = mVipTimeRangeItemList.get(i); // String userStartTime = vipTimeRangeItem.getStartTime(); // String userEndTime = vipTimeRangeItem.getEndTime(); // //早于(不包含)VIP开始时间,或者晚于(不包含)VIP结束时间 // if (i > 0) { // ordinaryBuilder.append(" AND "); // } // ordinaryBuilder.append("(t.satellite_time<'" + userStartTime + "' OR t.satellite_time>'" + userEndTime + "')"); // } // ordinaryBuilder.append(")"); // ordinaryBuilder.append(" ORDER BY t.satellite_time DESC"); // String ordinarySql = ordinaryBuilder.toString(); // log.info(sysUserEntity.getCountyName() + ":ordinarySql:" + ordinarySql); // List voList1 = firePointOrdinaryDao.customQuery(ordinarySql); // // StringBuilder preciseBuilder = new StringBuilder(commonSql); // preciseBuilder.append(" FROM fire_point_precise AS t"); // preciseBuilder.append(" WHERE (t.town_code LIKE '" + mNoRedundantUserCode + "%')"); // preciseBuilder.append(" AND ("); // for (int i = 0; i < mVipTimeRangeItemList.size(); i++) { // VipTimeRangeBean.VipTimeRangeItemBean vipTimeRangeItem = mVipTimeRangeItemList.get(i); // String userStartTime = vipTimeRangeItem.getStartTime(); // String userEndTime = vipTimeRangeItem.getEndTime(); // //晚于(包含)VIP开始时间,并且早于(包含)VIP结束时间 // if (i > 0) { // preciseBuilder.append(" OR "); // } // preciseBuilder.append("(t.satellite_time>='" + userStartTime + "' AND t.satellite_time<='" + userEndTime + "')"); // } // preciseBuilder.append(")"); // preciseBuilder.append(" ORDER BY t.satellite_time DESC"); // String preciseSql = preciseBuilder.toString(); // log.info(sysUserEntity.getCountyName() + ":preciseSql:" + preciseSql); // List voList2 = firePointPreciseDao.customQuery(preciseSql); // // //将两种数据来源的火点合并到一起 // List resultList = new ArrayList<>(); // resultList.addAll(voList1); // resultList.addAll(voList2); // //对合并后的结果进行排序 // resultList.sort(Comparator.comparing(AllFirePointVo::getSatelliteTime)); // // return new FirePointQueryResultBean(true, "", resultList); // // } } }