package com.objecteye.service.impl; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.objecteye.entity.*; import com.objecteye.mapper.SyAreaEquipmentMapper; import com.objecteye.mapper.SyEquipmentMapper; import com.objecteye.mapper.SyVehicleForbidenTaskMapper; import com.objecteye.pojo.RabbitMQVehicle; import com.objecteye.pojo.RabbitMqVehicleViolation; import com.objecteye.service.AreaEquipmentService; import com.objecteye.service.IVehicleViolationsService; import com.objecteye.utils.GlobalUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 车辆违规模块 * * @author liuhaoyu */ @Component public class VehicleViolationsServiceImpl implements IVehicleViolationsService { private final Logger log = LoggerFactory.getLogger(VehicleViolationsServiceImpl.class); @Autowired private SyVehicleForbidenTaskMapper syVehicleForbidenTaskMapper; @Autowired private SyEquipmentMapper syEquipmentMapper; @Autowired private SyAreaEquipmentMapper syAreaEquipmentMapper; @Autowired private RedisTemplate redisTemplate; @Autowired private AreaEquipmentService areaEquipmentService; @Autowired private MongoTemplate mongoTemplate; private static Map WEEK_MAP = new HashMap<>(); static { WEEK_MAP.put(1, "周一"); WEEK_MAP.put(2, "周二"); WEEK_MAP.put(3, "周三"); WEEK_MAP.put(4, "周四"); WEEK_MAP.put(5, "周五"); WEEK_MAP.put(6, "周六"); WEEK_MAP.put(7, "周日"); } /** * 特殊车辆确认置信度下限 */ private final double SPECIAL_VEHICLE_TYPE_LOWER_SCORS = 0.7; /** * 车辆违规置信度下限 */ private final double ILLEGAL_CONFIRM_LIMMIT = 0.9; /** * 同步还在激活状态的任务到redis */ private void syncForbiddenTask() { SyVehicleForbidenTaskExample syVehicleForbidenTaskExample = new SyVehicleForbidenTaskExample(); SyVehicleForbidenTaskExample.Criteria criteria = syVehicleForbidenTaskExample.createCriteria(); criteria.andStatusNotEqualTo(0); List forbiddenTasks = syVehicleForbidenTaskMapper.selectByExample(syVehicleForbidenTaskExample); Map> deviceIdTaskMap = new HashMap<>(); for (SyVehicleForbidenTask forbiddenTask : forbiddenTasks) { if (null == forbiddenTask || null == forbiddenTask.getDeviceId() || "".equals(forbiddenTask.getDeviceId())) { continue; } String[] deviceIdArr = forbiddenTask.getDeviceId().split(","); for (String deviceId : deviceIdArr) { List tempTasks = new ArrayList<>(); if (deviceIdTaskMap.containsKey(deviceId)) { tempTasks = deviceIdTaskMap.get(deviceId); } tempTasks.add(forbiddenTask); deviceIdTaskMap.put(deviceId, tempTasks); } } redisTemplate.delete(GlobalUtil.FORBIDDEN_TASK); redisTemplate.opsForHash().putAll(GlobalUtil.FORBIDDEN_TASK, deviceIdTaskMap); } /** * 禁行任务查询接口 * * @param currentpage 页码 * @param pagevolume 页码容量 * @param name 名称(非必填) * @return 结果集 */ @Override public PageResult forbiddenTaskQueryByPage(Integer currentpage, Integer pagevolume, String name) { SyVehicleForbidenTaskExample syVehicleForbidenTaskExample = new SyVehicleForbidenTaskExample(); SyVehicleForbidenTaskExample.Criteria criteria = syVehicleForbidenTaskExample.createCriteria(); if (null != name && !"".equals(name)) { criteria.andNameLike("%" + name + "%"); } PageInfo pageInfo = PageHelper.startPage(currentpage, pagevolume) .doSelectPageInfo(() -> syVehicleForbidenTaskMapper.selectByExample(syVehicleForbidenTaskExample)); List tempList = pageInfo.getList(); // 一次查询所有任务id对应的报警数 Aggregation aggregation = Aggregation.newAggregation( Aggregation.project("taskId"), Aggregation.group("taskId").count().as("count"), Aggregation.project("taskId", "count")); AggregationResults vehicleViolationAgg = mongoTemplate.aggregate(aggregation, "rabbitMqVehicleViolation", JSONObject.class); List taskWarningNumList = vehicleViolationAgg.getMappedResults(); Map taskWarningNumMap = new HashMap<>(); for (JSONObject jsonObject : taskWarningNumList) { if (null == jsonObject) { continue; } taskWarningNumMap.put(jsonObject.getString("_id"), jsonObject.getString("count")); } List resultList = new ArrayList<>(); // 拼接返回数据格式 for (SyVehicleForbidenTask forbiddenTask : tempList) { if (null == forbiddenTask) { continue; } SyVehicleForbiddenTaskOutput output = new SyVehicleForbiddenTaskOutput(); output.setId(String.valueOf(forbiddenTask.getId())); output.setName(forbiddenTask.getName()); output.setDescription(forbiddenTask.getDescription()); output.setStatus(null != forbiddenTask.getStatus() && 1 == forbiddenTask.getStatus() ? "工作中" : "已撤销"); output.setEffectStartTime(DateUtil.format(new Date(forbiddenTask.getEffectStartTime()), "yyyy-MM-dd HH:mm:ss")); output.setVehicleType(forbiddenTask.getVehicleType().replaceAll("1", "危化品车").replaceAll("2", "渣土车")); JSONObject forbiddenDetailObj = JSON.parseObject(forbiddenTask.getForbiddenDetailTime()); if (null != forbiddenDetailObj) { List forbiddenTimeList = new ArrayList<>(); for (int i = 1; i <= WEEK_MAP.size(); i++) { if (forbiddenDetailObj.containsKey(String.valueOf(i))) { forbiddenTimeList.add(WEEK_MAP.get(i) + " " + forbiddenDetailObj.getString(String.valueOf(i))); } } output.setForbiddenDetailTime(String.join(",", forbiddenTimeList)); } String warningNumber = taskWarningNumMap.getOrDefault(String.valueOf(forbiddenTask.getId()), "0"); output.setWarningNumber(warningNumber); output.setEquipment(getEquipmentNameByDeviceIds(forbiddenTask.getDeviceId())); resultList.add(output); } return new PageResult<>(pageInfo.getPages(), resultList); } /** * 禁行任务查询明细 * * @param id 主键 * @return 结果 */ @Override public SyVehicleForbidenTask forbiddenTaskDetail(String id) { SyVehicleForbidenTask forbidenTask = syVehicleForbidenTaskMapper.selectByPrimaryKey(Integer.valueOf(id)); if (forbidenTask != null) { String areaIds = forbidenTask.getAreaId(); if (areaIds != null && !"".equals(areaIds)) { List areaIdList = Arrays.stream(areaIds.split(",")).map(Integer::parseInt).collect(Collectors.toList()); SyAreaEquipmentExample syAreaEquipmentExample = new SyAreaEquipmentExample(); SyAreaEquipmentExample.Criteria criteria = syAreaEquipmentExample.createCriteria(); criteria.andIdIn(areaIdList); List syAreaEquipments = syAreaEquipmentMapper.selectByExample(syAreaEquipmentExample); String areaNames = syAreaEquipments.stream().map(SyAreaEquipment::getName).collect(Collectors.joining(",")); forbidenTask.setAreaName(areaNames); } } return forbidenTask; } /** * 禁行任务维护- 新增接口 * * @param syVehicleForbidenTask 请求参数 * @return 结果集 */ @Override public int forbiddenTaskAdd(SyVehicleForbidenTask syVehicleForbidenTask) { syVehicleForbidenTask.setEffectStartTime(System.currentTimeMillis()); if (syVehicleForbidenTask.getStatus() == null) { syVehicleForbidenTask.setStatus(1); } if (null != syVehicleForbidenTask.getAreaId() && !"".equals(syVehicleForbidenTask.getAreaId())) { syVehicleForbidenTask.setDeviceId(getDeviceIdsByAreaIds(syVehicleForbidenTask.getAreaId())); } int status = syVehicleForbidenTaskMapper.insertSelective(syVehicleForbidenTask); syncForbiddenTask(); return status; } /** * 禁行任务维护- 修改接口 * * @param syVehicleForbidenTask 请求参数 * @return 结果集 */ @Override public int forbiddenTaskUpdate(SyVehicleForbidenTask syVehicleForbidenTask) { if (null != syVehicleForbidenTask.getAreaId() && !"".equals(syVehicleForbidenTask.getAreaId())) { syVehicleForbidenTask.setDeviceId(getDeviceIdsByAreaIds(syVehicleForbidenTask.getAreaId())); } int status = syVehicleForbidenTaskMapper.updateByPrimaryKeySelective(syVehicleForbidenTask); syncForbiddenTask(); return status; } /** * 根据区域id获取对应的所有设备id * * @param areaIds 区域id 多个之间,间隔 * @return 设备id字符串 */ private String getDeviceIdsByAreaIds(String areaIds) { String[] areaIdArr = areaIds.split(","); Set deviceIdSet = new HashSet<>(); for (String areaId : areaIdArr) { deviceIdSet.addAll(areaEquipmentService.findCaptureById(Integer.parseInt(areaId))); } return deviceIdSet.stream().map(String::valueOf).collect(Collectors.joining(",")); } /** * 根据设备id获取对应的设备名称 * * @param deviceIds 设备ids * @return 名称 */ private String getEquipmentNameByDeviceIds(String deviceIds) { List deviceIdList = Arrays.stream(deviceIds.split(",")).map(Integer::parseInt).collect(Collectors.toList()); SyEquipmentExample syEquipmentExample = new SyEquipmentExample(); SyEquipmentExample.Criteria criteria = syEquipmentExample.createCriteria(); criteria.andIdIn(deviceIdList); List syAreaEquipments = syEquipmentMapper.selectByExample(syEquipmentExample); return syAreaEquipments.stream().map(SyEquipment::getEquipmentName).collect(Collectors.joining(",")); } /** * 禁行任务维护- 删除接口 * * @param ids 请求参数 * @return 结果集 */ @Override public int forbiddenTaskDelete(String[] ids) { int effectNum = 0; for (String id : ids) { if (null == id || "".equals(id)) { continue; } // 删除历史数据 mongoTemplate.remove(Query.query(Criteria.where("taskId").is(id)), RabbitMqVehicleViolation.class); // 删除任务 syVehicleForbidenTaskMapper.deleteByPrimaryKey(Integer.parseInt(id)); effectNum++; } syncForbiddenTask(); return effectNum; } /** * 布控任务监控 * * @param rabbitMqVehicle mq消息 */ @Override public void taskListener(RabbitMQVehicle rabbitMqVehicle) { RabbitMqVehicleViolation rabbitMqVehicleViolation = JSON.parseObject(JSON.toJSONString(rabbitMqVehicle), RabbitMqVehicleViolation.class); rabbitMqVehicleViolation.setBaseId(rabbitMqVehicleViolation.getId()); double specialScore = rabbitMqVehicleViolation.getVehicle_special_score(); // 非特殊车辆 if (specialScore >= SPECIAL_VEHICLE_TYPE_LOWER_SCORS) { // 特殊车辆处理 int deviceId = rabbitMqVehicleViolation.getDeviceid(); int specialType = rabbitMqVehicleViolation.getVehicle_special_type(); // 对激活的任务做判断 List availableForbiddenTasks = (List) redisTemplate.opsForHash().get(GlobalUtil.FORBIDDEN_TASK, String.valueOf(deviceId)); if (null != availableForbiddenTasks && availableForbiddenTasks.size() != 0) { // 检测是否违规, 违规一次即跳出循环 for (SyVehicleForbidenTask forbiddenTask : availableForbiddenTasks) { List vehicleType = Arrays.stream(forbiddenTask.getVehicleType().split(",")).collect(Collectors.toList()); if (vehicleType.contains(String.valueOf(specialType))) { // 是否检测时间段内 String pictime = DateUtil.format(new Date(rabbitMqVehicleViolation.getPictime()), "yyyy-MM-dd HH:mm:ss"); JSONObject forbiddenDetail = JSON.parseObject(forbiddenTask.getForbiddenDetailTime()); int dayOfWeek = DateUtil.dayOfWeek(new Date(rabbitMqVehicleViolation.getPictime())); String week = String.valueOf(dayOfWeek == 1 ? 7 : dayOfWeek - 1); String forbiddenDayDetail = forbiddenDetail.getString(week); if (null != forbiddenDayDetail) { String[] timeScopeArr = forbiddenDayDetail.split(","); for (String timeScope : timeScopeArr) { String startTime = pictime.split(" ")[0] + " " + timeScope.split("-")[0]; String endTime = pictime.split(" ")[0] + " " + timeScope.split("-")[1]; if (betweenMs(pictime, startTime) < 0 && betweenMs(pictime, endTime) > 0) { rabbitMqVehicleViolation.setId(UUID.randomUUID().toString()); rabbitMqVehicleViolation.setTaskId(forbiddenTask.getId()); mongoTemplate.insert(rabbitMqVehicleViolation); break; } } } } } } } } /** * 获取时间差值 带正负 * * @param beginDate 开始时间 * @param endDate 结束时间 * @return 时间差值 */ private long betweenMs(String beginDate, String endDate) { return DateUtil.between(DateUtil.parse(beginDate), DateUtil.parse(endDate), DateUnit.MS, false); } /** * 车辆违规查询 * * @param params 请求参数 * @param useViolationTable 是否是查询禁行违规 * @return 结果集 */ @Override public PageResult vehicleViolationQueryByPage(VehicleViolationsForbidenTaskQueryParams params, boolean useViolationTable) { int pageNum = params.getCurrentpage(); int pageSize = params.getPagevolume(); boolean ifNoCheckStatus = true; Criteria criteria = new Criteria(); if (null != params.getCustomsPass() && !"".equals(params.getCustomsPass())) { List deviceIds = areaEquipmentService.findCaptureById(Integer.parseInt(params.getCustomsPass())); criteria.and("deviceid").in(deviceIds); } Long startTime = params.getStartTime(); Long endTime = params.getEndTime(); if (null == startTime) { if (null != endTime) { criteria.and("pictime").lte(endTime); } } else if (null == endTime) { criteria.and("pictime").gte(startTime); } else { criteria.andOperator(Criteria.where("pictime").gte(startTime), Criteria.where("pictime").lte(endTime)); } List orCriteriaList = new ArrayList<>(); if (null != params.getIfNoPlate() && 1 == params.getIfNoPlate()) { orCriteriaList.add(Criteria.where("vehicleplatedetectscore").is(0)); ifNoCheckStatus = false; } if (null != params.getIfStainedPlate() && 1 == params.getIfStainedPlate()) { String regex = "^.*\\*.*$"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); orCriteriaList.add(Criteria.where("vehicle_plate_hphm").regex(pattern)); ifNoCheckStatus = false; } if (null != params.getIfDriverNoBelt() && 1 == params.getIfDriverNoBelt()) { orCriteriaList.add(Criteria.where("vehicle_illegal_driver_belt_status").is(1000) .and("vehicle_illegal_driver_belt_confidence").gte(ILLEGAL_CONFIRM_LIMMIT)); ifNoCheckStatus = false; } if (null != params.getIfCopilotNoBelt() && 1 == params.getIfCopilotNoBelt()) { orCriteriaList.add(Criteria.where("vehicle_illegal_copilot_belt_status").is(1000) .and("vehicle_illegal_copilot_belt_confidence").gte(ILLEGAL_CONFIRM_LIMMIT)); ifNoCheckStatus = false; } if (null != params.getIfPhone() && 1 == params.getIfPhone()) { orCriteriaList.add(Criteria.where("vehicle_illegal_driver_phone_status").is(1000) .and("vehicle_illegal_driver_phone_confidence").gte(ILLEGAL_CONFIRM_LIMMIT)); ifNoCheckStatus = false; } if (null != params.getIfSmoke() && 1 == params.getIfSmoke()) { orCriteriaList.add(Criteria.where("vehicle_illegal_driver_smoke_status").is(1000) .and("vehicle_illegal_driver_smoke_confidence").gte(ILLEGAL_CONFIRM_LIMMIT)); ifNoCheckStatus = false; } boolean ifMuckCar = null != params.getIfMuckCar() && 1 == params.getIfMuckCar(); boolean ifDangerousChemicals = null != params.getIfDangerousChemicals() && 1 == params.getIfDangerousChemicals(); if (ifMuckCar) { orCriteriaList.add(Criteria.where("vehicle_special_type").is(2) .and("vehicle_special_score").gte(SPECIAL_VEHICLE_TYPE_LOWER_SCORS)); ifNoCheckStatus = false; } if (ifDangerousChemicals) { orCriteriaList.add(Criteria.where("vehicle_special_type").is(1) .and("vehicle_special_score").gte(SPECIAL_VEHICLE_TYPE_LOWER_SCORS)); ifNoCheckStatus = false; } criteria.orOperator(orCriteriaList.stream().toArray(Criteria[]::new)); Query query = Query.query(criteria).limit(pageSize).skip((pageNum - 1) * pageSize); query.fields().include("id"); query.fields().include("baseId"); query.fields().include("pictime"); query.fields().include("snapshoturl"); query.fields().include("personUrl"); query.fields().include("vehicle_plate_hphm"); query.fields().include("equipmentName"); return getVehicleViolationQueryResult(query, useViolationTable, ifNoCheckStatus, pageSize); } /** * 车辆违规查询- 获得查询结果 * * @param query 过滤条件 * @param useViolationTable 是否是使用违规车辆表 * @param ifNoCheckStatus 是否无勾选项 * @return 结果集 */ private PageResult getVehicleViolationQueryResult(Query query, boolean useViolationTable, boolean ifNoCheckStatus, int pageSize) { if (ifNoCheckStatus) { return new PageResult<>(0, new ArrayList<>()); } if (useViolationTable) { List vehicleViolations = mongoTemplate.find(query, RabbitMqVehicleViolation.class); List resultList = new ArrayList<>(); for (RabbitMqVehicleViolation rabbitMqVehicleViolation : vehicleViolations) { if (null == rabbitMqVehicleViolation) { continue; } VehicleSimpleResult vehicleSimpleResult = new VehicleSimpleResult(); vehicleSimpleResult.setPicurl(rabbitMqVehicleViolation.getSnapshoturl()); vehicleSimpleResult.setId(rabbitMqVehicleViolation.getBaseId()); vehicleSimpleResult.setPersonUrl(rabbitMqVehicleViolation.getPersonUrl()); vehicleSimpleResult.setPictime(DateUtil.format(new Date(rabbitMqVehicleViolation.getPictime()), "yyyy-MM-dd HH:mm:ss")); vehicleSimpleResult.setPlateNumber(rabbitMqVehicleViolation.getVehicle_plate_hphm()); vehicleSimpleResult.setEquipmentName(rabbitMqVehicleViolation.getEquipmentName() == null ? "" : rabbitMqVehicleViolation.getEquipmentName()); resultList.add(vehicleSimpleResult); } long total = mongoTemplate.count(query, RabbitMqVehicleViolation.class); int totalPage = (int) Math.ceil((double) total / pageSize); return new PageResult<>(totalPage, resultList); } else { List rabbitMqVehicles = mongoTemplate.find(query, RabbitMQVehicle.class); List resultList = new ArrayList<>(); for (RabbitMQVehicle rabbitMqVehicle : rabbitMqVehicles) { if (null == rabbitMqVehicle) { continue; } VehicleSimpleResult vehicleSimpleResult = new VehicleSimpleResult(); vehicleSimpleResult.setId(rabbitMqVehicle.getId()); vehicleSimpleResult.setPicurl(rabbitMqVehicle.getSnapshoturl()); vehicleSimpleResult.setPersonUrl(rabbitMqVehicle.getPersonUrl()); vehicleSimpleResult.setPictime(DateUtil.format(new Date(rabbitMqVehicle.getPictime()), "yyyy-MM-dd HH:mm:ss")); vehicleSimpleResult.setPlateNumber(rabbitMqVehicle.getVehicle_plate_hphm()); vehicleSimpleResult.setEquipmentName(rabbitMqVehicle.getEquipmentName()); resultList.add(vehicleSimpleResult); } long total = mongoTemplate.count(query, RabbitMQVehicle.class); int totalPage = (int) Math.ceil((double) total / pageSize); return new PageResult<>(totalPage, resultList); } } }