package com.ycl.platform.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ycl.platform.domain.entity.WorkOrder;
|
import com.ycl.platform.domain.entity.YwThreshold;
|
import com.ycl.platform.domain.result.HK.FaceDeviceInspectionResult;
|
import com.ycl.platform.domain.result.HK.VehicleDeviceInspectionResult;
|
import com.ycl.platform.mapper.YwThresholdMapper;
|
import com.ycl.platform.service.IYwThresholdService;
|
import com.ycl.platform.service.WorkOrderService;
|
import com.ycl.utils.ip.PingUtil;
|
import constant.YwThreadConstants;
|
import enumeration.CompareType;
|
import enumeration.ErrorType;
|
import enumeration.general.BusinessTypeEnum;
|
import enumeration.general.WorkOrderStatusEnum;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
import utils.DateUtils;
|
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
/**
|
* 运维阈值Service业务层处理
|
*
|
* @author gonghl
|
* @date 2024-07-19
|
*/
|
@Service
|
@Slf4j
|
public class YwThresholdServiceImpl extends ServiceImpl<YwThresholdMapper, YwThreshold> implements IYwThresholdService {
|
@Autowired
|
private YwThresholdMapper ywThresholdMapper;
|
|
@Autowired
|
private WorkOrderService workOrderService;
|
|
/**
|
* 查询运维阈值
|
*
|
* @param id 运维阈值主键
|
* @return 运维阈值
|
*/
|
@Override
|
public YwThreshold selectYwThresholdById(Long id) {
|
return ywThresholdMapper.selectYwThresholdById(id);
|
}
|
|
/**
|
* 查询运维阈值列表
|
*
|
* @param ywThreshold 运维阈值
|
* @return 运维阈值
|
*/
|
@Override
|
public Map<String, List<YwThreshold>> selectYwThresholdList(YwThreshold ywThreshold) {
|
List<YwThreshold> ywThresholds = ywThresholdMapper.selectYwThresholdList(ywThreshold);
|
Map<String, List<YwThreshold>> map = ywThresholds.stream().collect(Collectors.groupingBy(YwThreshold::getMonitorType));
|
return map;
|
}
|
|
/**
|
* 新增运维阈值
|
*
|
* @param ywThreshold 运维阈值
|
* @return 结果
|
*/
|
@Override
|
public int insertYwThreshold(YwThreshold ywThreshold) {
|
ywThreshold.setCreateTime(DateUtils.getNowDate());
|
return ywThresholdMapper.insertYwThreshold(ywThreshold);
|
}
|
|
/**
|
* 修改运维阈值
|
*
|
* @param list 运维阈值
|
* @return 结果
|
*/
|
@Override
|
public Boolean updateYwThreshold(List<YwThreshold> list) {
|
list.forEach(item -> item.setCreateTime(new Date()));
|
return updateBatchById(list);
|
}
|
|
/**
|
* 批量删除运维阈值
|
*
|
* @param ids 需要删除的运维阈值主键
|
* @return 结果
|
*/
|
@Override
|
public int deleteYwThresholdByIds(Long[] ids) {
|
return ywThresholdMapper.deleteYwThresholdByIds(ids);
|
}
|
|
/**
|
* 删除运维阈值信息
|
*
|
* @param id 运维阈值主键
|
* @return 结果
|
*/
|
@Override
|
public int deleteYwThresholdById(Long id) {
|
return ywThresholdMapper.deleteYwThresholdById(id);
|
}
|
|
/**
|
* 判断视频阈值是否满足下发条件
|
*
|
* @param list
|
*/
|
@Override
|
public void videoCheck(List list) {
|
|
}
|
|
@Override
|
public void errorTypeCheckUY(List list) {
|
// 平台离线故障检测
|
if (CollectionUtils.isEmpty(list)) {
|
Boolean ping = PingUtil.ping("", 5);
|
if (! ping) {
|
|
}
|
}
|
// 设备离线故障检测
|
|
// 信号缺失故障检测
|
|
// 画面偏色故障检测
|
|
// 雪花干扰故障检测
|
|
// 条纹干扰故障检测
|
|
// 画面遮挡故障检测
|
|
// 清晰度异常检测
|
|
// 亮度异常故障检测
|
}
|
|
/**
|
* 判断人脸阈值是否满足下发条件
|
*
|
* @param list
|
*/
|
@Override
|
public void faceCheck(List<FaceDeviceInspectionResult> list) {
|
Map<String, YwThreshold> thresholdMap = getYwThresholdMap(BusinessTypeEnum.FACE.name());
|
//准备下发工单集合
|
List<WorkOrder> distributeList = new ArrayList<>();
|
//准备自动生成工单集合
|
List<WorkOrder> workOrderList = new ArrayList<>();
|
//处理接口数据
|
for (FaceDeviceInspectionResult result : list) {
|
if (result == null) {
|
log.error("人脸对象数据为空");
|
continue;
|
}
|
WorkOrder workOrder = new WorkOrder();
|
//检查时钟准确率
|
Float clockPercent = result.getSnapClock().getClockPercent();
|
check(YwThreadConstants.Face_ClockPercent, clockPercent, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.CLOCK_RIGHT.getValue());
|
//检查数据及时率
|
Float timelyPercent = result.getSnapTimely().getTimelyPercent();
|
check(YwThreadConstants.Face_TimelyPercent, timelyPercent, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.DATA_TIMELY_ERROR.getValue());
|
//检查持续无数据天数
|
Integer continueNoDataCount = result.getContinueNoDataCount();
|
check(YwThreadConstants.Face_ContinueNoDataCount, continueNoDataCount, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.LONG_DAY_NO_DATA.getValue());
|
//检查不唯一数据量
|
Integer nouniqueCount = result.getSnapUnique().getNouniqueCount();
|
check(YwThreadConstants.Face_NouniqueCount, nouniqueCount, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.NOT_UNIQUE_DATA_VOLUME.getValue());
|
//检查人脸低评分率
|
Float lowScorePercent = result.getSnapValidity().getLowScorePercent();
|
check(YwThreadConstants.Face_LowScorePercent, lowScorePercent, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.FACE_LOW.getValue());
|
//检查建模失败率
|
Float failPercent = result.getSnapValidity().getFailPercent();
|
check(YwThreadConstants.Face_FailPercent, failPercent, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.MODELING_FAIL.getValue());
|
// 点位在线率
|
if (2 == result.getSnapResult()) {
|
workOrder.setSerialNumber(result.getExternalIndexCode());
|
workOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
|
if (CollectionUtils.isEmpty(workOrder.getErrorTypeList())) {
|
workOrder.setErrorTypeList(new ArrayList<>());
|
workOrder.getErrorTypeList().add(ErrorType.DEVICE_OFFLINE.getValue());
|
} else {
|
workOrder.getErrorTypeList().add(ErrorType.DEVICE_OFFLINE.getValue());
|
}
|
}
|
if (WorkOrderStatusEnum.WAIT_DISTRIBUTE.equals(workOrder.getStatus())) {
|
workOrderList.add(workOrder);
|
} else if (WorkOrderStatusEnum.DISTRIBUTED.equals(workOrder.getStatus())) {
|
distributeList.add(workOrder);
|
}
|
}
|
/** 添加工单 */
|
workOrderService.innerAddWorkOrder(workOrderList);
|
workOrderService.innerAddWorkOrder(distributeList);
|
}
|
|
/**
|
* 判断车辆阈值是否满足下发条件
|
*
|
* @param list
|
*/
|
@Override
|
public void carCheck(List<VehicleDeviceInspectionResult> list) {
|
Map<String, YwThreshold> thresholdMap = getYwThresholdMap(BusinessTypeEnum.CAR.name());
|
//准备下发工单集合
|
List<WorkOrder> distributeList = new ArrayList<>();
|
//准备自动生成工单集合
|
List<WorkOrder> workOrderList = new ArrayList<>();
|
//处理接口数据
|
for (VehicleDeviceInspectionResult result : list) {
|
if (result == null) {
|
log.error("车辆对象数据为空");
|
continue;
|
}
|
WorkOrder workOrder = new WorkOrder();
|
//检查持续无数据天数
|
Integer continueNoDataCount = result.getContinueNoDataCount();
|
check(YwThreadConstants.Car_ContinueNoDataCount, continueNoDataCount, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.LONG_DAY_NO_DATA.getValue());
|
//检查时钟准确率
|
Float clockPercent = result.getSnapClock().getClockPercent();
|
check(YwThreadConstants.Car_ClockPercent, clockPercent, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.CLOCK_RIGHT.getValue());
|
//检查数据及时率
|
Float timelyPercentResult = result.getSnapTimely().getTimelyPercent();
|
check(YwThreadConstants.Car_TimelyPercent, timelyPercentResult, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.LESS_THAN_EQ, ErrorType.DATA_TIMELY_ERROR.getValue());
|
//检查不唯一数据量
|
Integer nouniqueCountResult = result.getSnapUnique().getNouniqueCount();
|
check(YwThreadConstants.Car_NouniqueCount, nouniqueCountResult, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.NOT_UNIQUE_DATA_VOLUME.getValue());
|
//检查白天未识别量
|
Integer dayNoNumberCountResult = result.getSnapPlate().getDayNoNumberCount();
|
check(YwThreadConstants.Car_DayNoNumberCount, dayNoNumberCountResult, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.UNRECOGNIZED_DAY_VOLUME.getValue());
|
//车辆六项属性不完整量
|
Integer noIntegrityCountResult = result.getIntegrity().getNoIntegrityCount();
|
check(YwThreadConstants.Car_NoIntegrityCount, noIntegrityCountResult, result.getExternalIndexCode(), thresholdMap, workOrder, CompareType.MORE_THAN_EQ, ErrorType.CAR_SIX.getValue());
|
// 点位在线率
|
if (2 == result.getSnapResult()) {
|
workOrder.setSerialNumber(result.getExternalIndexCode());
|
workOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
|
if (CollectionUtils.isEmpty(workOrder.getErrorTypeList())) {
|
workOrder.setErrorTypeList(new ArrayList<>());
|
workOrder.getErrorTypeList().add(ErrorType.DEVICE_OFFLINE.getValue());
|
} else {
|
workOrder.getErrorTypeList().add(ErrorType.DEVICE_OFFLINE.getValue());
|
}
|
}
|
if (WorkOrderStatusEnum.WAIT_DISTRIBUTE.equals(workOrder.getStatus())) {
|
workOrderList.add(workOrder);
|
} else if (WorkOrderStatusEnum.DISTRIBUTED.equals(workOrder.getStatus())) {
|
distributeList.add(workOrder);
|
}
|
}
|
/** 添加工单 */
|
workOrderService.innerAddWorkOrder(workOrderList);
|
workOrderService.innerAddWorkOrder(distributeList);
|
}
|
|
/**
|
* 把阈值条件查出来,转成map
|
*
|
* @param name
|
* @return
|
*/
|
private Map<String, YwThreshold> getYwThresholdMap(String name) {
|
return ywThresholdMapper.selectList(
|
new QueryWrapper<YwThreshold>().eq("monitor_type", name)
|
).stream().collect(Collectors.toMap(
|
YwThreshold::getKey,
|
Function.identity()
|
));
|
}
|
|
/**
|
* 检查阈值
|
*
|
* @param key 某阈值标识
|
* @param value 接口获取到的值
|
* @param serialNumber 国标码
|
* @param thresholds 阈值条件map
|
* @param compareType 比较方式:>= <=
|
* @param errorType 故障类型
|
* @param <T>
|
*/
|
private <T extends Comparable<T>> void check(String key, T value, String serialNumber, Map<String, YwThreshold> thresholds, WorkOrder workOrder, CompareType compareType,String errorType) {
|
Optional.ofNullable(value).ifPresentOrElse(
|
v -> {
|
YwThreshold ywThreshold = thresholds.get(key);
|
//转换类型
|
T thresholdValue = parseThreshold(ywThreshold.getValueAuto(), value.getClass());
|
T thresholdAutoValue = parseThreshold(ywThreshold.getValue(), value.getClass());
|
//比较大小,加入到对应待处理集合
|
if (compareType.compare(v, thresholdAutoValue)) {
|
//自动下发工单
|
workOrder.setSerialNumber(serialNumber);
|
workOrder.setStatus(WorkOrderStatusEnum.WAIT_DISTRIBUTE);
|
if (CollectionUtils.isEmpty(workOrder.getErrorTypeList())) {
|
workOrder.setErrorTypeList(new ArrayList<>());
|
workOrder.getErrorTypeList().add(errorType);
|
} else {
|
workOrder.getErrorTypeList().add(errorType);
|
}
|
} else if (compareType.compare(v, thresholdValue)) {
|
//进入工单代下发
|
workOrder.setSerialNumber(serialNumber);
|
workOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
|
if (CollectionUtils.isEmpty(workOrder.getErrorTypeList())) {
|
workOrder.setErrorTypeList(new ArrayList<>());
|
workOrder.getErrorTypeList().add(errorType);
|
} else {
|
workOrder.getErrorTypeList().add(errorType);
|
}
|
}
|
},
|
() -> log.error("{} 为空: {}", thresholds.get(key).getName(), serialNumber)
|
);
|
}
|
|
private <T extends Comparable<T>> T parseThreshold(String thresholdStr, Class<?> type) {
|
if (Integer.class.equals(type)) {
|
return (T) Integer.valueOf(thresholdStr);
|
} else if (Float.class.equals(type)) {
|
return (T) Float.valueOf(thresholdStr);
|
} else if (Double.class.equals(type)) {
|
return (T) Double.valueOf(thresholdStr);
|
} else if (Long.class.equals(type)) {
|
return (T) Long.valueOf(thresholdStr);
|
} else {
|
throw new IllegalArgumentException("不支持转换类型" + type);
|
}
|
}
|
|
}
|