xiangpei
2024-08-29 4d25380fe077f82b45f00e83ecb6d93e76c95554
ycl-server/src/main/java/com/ycl/task/OsdTask.java
@@ -1,18 +1,239 @@
package com.ycl.task;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mongodb.client.result.DeleteResult;
import com.ycl.api.DH.module.LoginModule;
import com.ycl.api.DH.utils.DHApi;
import com.ycl.api.HK.HKApi;
import com.ycl.platform.domain.entity.TMonitor;
import com.ycl.platform.domain.result.OSDResult;
import com.ycl.platform.domain.result.UY.MonitorQualifyResult;
import com.ycl.platform.domain.result.UY.OsdCheckResult;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.service.UYErrorTypeCheckService;
import com.ycl.utils.DateUtils;
import com.ycl.utils.StringUtils;
import constant.ApiConstants;
import enumeration.DeviceType;
import enumeration.general.AreaDeptEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component("OsdTask")
public class OsdTask {
    @Value("${HK.userName}")
    public String HKUserName;
    @Value("${HK.password}")
    public String HKPassword;
    @Value("${DH.userName}")
    public String DHUserName;
    @Value("${DH.password}")
    public String DHPassword;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private TMonitorMapper monitorMapper;
    @Autowired
    private UYErrorTypeCheckService uyErrorTypeCheckService;
    private static final ExecutorService executorService = new ThreadPoolExecutor(8,
            24,
            5000,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );
    /**
     * 通过查mongoDB每日一机一档数据获取设备ip
     * 通过设备ip、品牌调用不同api获取osd信息
     * 比对mongoDB一机一档信息,整理成result存入mongo
     * 同步品牌到mysql
     */
    public void getOSD() {
        HKApi.getOsdByIP("51.95.68.80");
        long loginId = LoginModule.login("51.95.67.189", 80, "admin", "zg@2024dx");
        String osdTime = LoginModule.getOsdTime();
        LoginModule.logout();
        //批量修改海康品牌集合
        List<String> hkList = new ArrayList<>();
        //批量修改大华品牌集合
        List<String> dhList = new ArrayList<>();
        //批量修改宇视品牌集合
        List<String> ysList = new ArrayList<>();
        List<OSDResult> osdResultList = new ArrayList<>();
        //查一机一档monitor
        Query query = new Query(Criteria.where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date())));
        List<MonitorQualifyResult> oneMachineFileResults = mongoTemplate.find(query, MonitorQualifyResult.class);
        //需要考核的数据
        List<String> serialNumbers = oneMachineFileResults.stream().map(result -> result.getSerialNumber().getValue()).collect(Collectors.toList());
        List<TMonitor> monitors = monitorMapper.selectByNumbers(serialNumbers);
        for (TMonitor monitor : monitors) {
            executorService.submit(() -> {
                if (DeviceType.HK.getType().equals(monitor.getDeviceType())) {
                    //海康品牌
                    OSDResult osd = HKApi.getOsdByIP(monitor.getIp(), HKUserName, HKPassword);
                    if (checkSuccess(osdResultList, monitor, osd)) return;
                } else if (DeviceType.DH.getType().equals(monitor.getDeviceType())) {
                    //大华品牌
                    OSDResult osd = DHApi.getOsd(monitor.getIp(), DHUserName, DHPassword);
                    if (checkSuccess(osdResultList, monitor, osd)) return;
                } else if (DeviceType.YS.getType().equals(monitor.getDeviceType())) {
                    //TODO:宇视api
                }
                //未知品牌或者api调用失败,挨个执行所有api
                OSDResult osd = tryAllApi(monitor, hkList, dhList, ysList);
                if (osd != null) {
                    synchronized (osdResultList) {
                        osdResultList.add(osd);
                    }
                }
            });
        }
        executorService.shutdown();
        //结束api执行,开始校验
        List<OsdCheckResult> checkResults = new ArrayList<>();
        Map<String, TMonitor> monitorMap = monitors.stream().collect(Collectors.toMap(TMonitor::getSerialNumber, Function.identity()));
        for (OSDResult osdResult : osdResultList) {
            TMonitor monitor = monitorMap.get(osdResult.getSerialNumber());
            //封装OsdCheckResult
            OsdCheckResult osdCheckResult = getOsdCheckResult(osdResult, monitor);
            checkCorrect(osdResult, monitor, osdCheckResult);
            checkResults.add(osdCheckResult);
        }
        //结果存入mongo
        if(CollectionUtils.isEmpty(checkResults)){
            //如果今天存在之前的数据先删除
            Query pyQuery = new Query(Criteria
                    .where("mongoCreateTime").gte(DateUtils.getDayStart(new Date())).lt(DateUtils.getDayEnd(new Date())));
            DeleteResult result = mongoTemplate.remove(pyQuery, OsdCheckResult.class);
            //存放在mongo中
            mongoTemplate.insertAll(checkResults);
            // 工单生成
            uyErrorTypeCheckService.osdCheck(checkResults);
        }
        //修改数据库品牌
        if(!CollectionUtils.isEmpty(hkList)){
            monitorMapper.batchUpdateDeviceType(hkList,DeviceType.HK.getType());
        }
        if(!CollectionUtils.isEmpty(dhList)){
            monitorMapper.batchUpdateDeviceType(dhList,DeviceType.DH.getType());
        }
        //TODO:宇视
        log.info("结束获取OSD");
    }
    private OsdCheckResult getOsdCheckResult(OSDResult osdResult, TMonitor monitor) {
        OsdCheckResult osdCheckResult = new OsdCheckResult();
        osdCheckResult.setDeviceNo(osdResult.getSerialNumber());
        osdCheckResult.setIp(monitor.getIp());
        osdCheckResult.setDeviceType(monitor.getCameraFunType());
        osdCheckResult.setCheckTime(osdResult.getCheckTime());
        osdCheckResult.setSetTime(osdResult.getOsdTime());
        osdCheckResult.setOsdProvince(osdResult.getOSD1());
        osdCheckResult.setOsdCity(osdResult.getOSD2());
        osdCheckResult.setOsdPart(osdResult.getOSD3());
        osdCheckResult.setOsdLB(osdResult.getOSD4());
        osdCheckResult.setOsdName(osdResult.getName());
        return osdCheckResult;
    }
    private void checkCorrect(OSDResult osdResult, TMonitor monitor, OsdCheckResult osdCheckResult) {
        //检查时间是否正确
        if (osdResult.getCheckTime() != null && osdResult.getOsdTime() != null) {
            long checkTime = osdResult.getCheckTime().getTime();
            long osdTime = osdResult.getOsdTime().getTime();
            long timeDiff = (checkTime - osdTime) / 1000;
            if (timeDiff <=60) {
                osdCheckResult.setOsdTimeCorrect(ApiConstants.OSD_Correct);
            } else {
                osdCheckResult.setOsdTimeCorrect(ApiConstants.OSD_Error);
            }
        }
        //检查通道名是否正确
        if (!StringUtils.isEmpty(osdResult.getName()) && !StringUtils.isEmpty(monitor.getName())) {
            if (monitor.getName().equals(osdResult.getName())) {
                osdCheckResult.setOsdNameCorrect(ApiConstants.OSD_Correct);
            } else {
                osdCheckResult.setOsdNameCorrect(ApiConstants.OSD_Error);
            }
        }
        //检查省是否正确
        if (!StringUtils.isEmpty(osdResult.getOSD1())) {
            if ("四川".equals(osdResult.getOSD1())) {
                osdCheckResult.setOsdProvinceCorrect(ApiConstants.OSD_Correct);
            } else {
                osdCheckResult.setOsdProvinceCorrect(ApiConstants.OSD_Error);
            }
        }
        //检查市是否正确
        if (!StringUtils.isEmpty(osdResult.getOSD2())) {
            if ("自贡".equals(osdResult.getOSD2())) {
                osdCheckResult.setOsdCityCorrect(ApiConstants.OSD_Correct);
            } else {
                osdCheckResult.setOsdCityCorrect(ApiConstants.OSD_Error);
            }
        }
        //检查区县是否正确
        if (!StringUtils.isEmpty(osdResult.getOSD3())) {
            AreaDeptEnum areaDeptEnum = AreaDeptEnum.fromCode(monitor.getSerialNumber().substring(0, 6));
            if (areaDeptEnum != null && osdResult.getOSD3().equals(areaDeptEnum.getName())) {
                osdCheckResult.setOsdPartCorrect(ApiConstants.OSD_Correct);
            } else {
                osdCheckResult.setOsdPartCorrect(ApiConstants.OSD_Error);
            }
        }
    }
    private boolean checkSuccess(List<OSDResult> osdResultList, TMonitor monitor, OSDResult osd) {
        if (osd != null) {
            osd.setSerialNumber(monitor.getSerialNumber());
            synchronized (osdResultList) {
                osdResultList.add(osd);
            }
            return true;
        } else {
            return false;
        }
    }
    private OSDResult tryAllApi(TMonitor monitor, List<String> hkList, List<String> dhList, List<String> ysList) {
        //尝试海康的api
        OSDResult hkosd = HKApi.getOsdByIP(monitor.getIp(), HKUserName, HKPassword);
        if (hkosd != null) {
            hkosd.setSerialNumber(monitor.getSerialNumber());
            synchronized (hkList) {
                hkList.add(monitor.getSerialNumber());
            }
            return hkosd;
        }
        //尝试大华的api
        OSDResult dhosd = DHApi.getOsd(monitor.getIp(), DHUserName, DHPassword);
        if (dhosd != null) {
            dhosd.setSerialNumber(monitor.getSerialNumber());
            synchronized (dhList) {
                dhList.add(monitor.getSerialNumber());
            }
            return dhosd;
        }
        //TODO:宇视api
        return null;
    }
}