aijinhui
2023-12-14 0306d5836a7a56614e01af35b9e70f0224b47cb2
ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java
@@ -1,669 +1,725 @@
package com.ruoyi.inspect.service.impl;
import java.text.SimpleDateFormat;
import java.util.*;
import com.ruoyi.alarmpoints.well.domain.ArdAlarmpointsWell;
import com.ruoyi.alarmpoints.well.mapper.ArdAlarmpointsWellMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.mapper.ArdCamerasMapper;
import com.ruoyi.device.hiksdk.config.MinioClientSingleton;
import com.ruoyi.device.hiksdk.service.IHikClientService;
import com.ruoyi.inspect.domain.ArdVideoInspectRecord;
import com.ruoyi.inspect.mapper.ArdVideoInspectRecordMapper;
import com.ruoyi.inspect.mapper.ArdVideoInspectTaskStepMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.inspect.domain.ArdVideoInspectTaskStep;
import com.ruoyi.inspect.mapper.ArdVideoInspectTaskMapper;
import com.ruoyi.inspect.domain.ArdVideoInspectTask;
import com.ruoyi.inspect.service.IArdVideoInspectTaskService;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
 * 视频巡检任务Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-30
 */
@Service
@Slf4j(topic = "PatrolInspectionTask")
public class ArdVideoInspectTaskServiceImpl implements IArdVideoInspectTaskService {
    @Resource
    private ArdVideoInspectTaskMapper ardVideoInspectTaskMapper;
    @Resource
    private ArdVideoInspectTaskStepMapper ardVideoInspectTaskStepMapper;
    @Resource
    private ArdAlarmpointsWellMapper ardAlarmpointsWellMapper;
    @Resource
    private ArdVideoInspectRecordMapper ardVideoInspectRecordMapper;
    @Resource
    private ArdCamerasMapper ardCamerasMapper;
    @Resource
    private IHikClientService hikClientService;
    @Resource
    private ArdCamerasMapper camerasMapper;
    @PostConstruct
    public void initTask() {
        List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(new ArdVideoInspectTask());
        for (ArdVideoInspectTask ardVideoInspectTask : ardVideoInspectTasks) {
            /*启动后将所有手动任务置为关闭,所有任务当前步骤信息清空*/
            if (ardVideoInspectTask.getInspectMode().equals("手动")) {
                ardVideoInspectTask.setMenualSwitch("关");
            }
            ardVideoInspectTask.setCurrentStepId("");
            ardVideoInspectTask.setCurrentStepStartTime("");
            ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
        }
    }
    /**
     * 查询视频巡检任务
     *
     * @param id 视频巡检任务主键
     * @return 视频巡检任务
     */
    @Override
    public ArdVideoInspectTask selectArdVideoInspectTaskById(String id) {
        return ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(id);
    }
    /**
     * 查询视频巡检任务列表
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 视频巡检任务
     */
    @Override
    public List<ArdVideoInspectTask> selectArdVideoInspectTaskList(ArdVideoInspectTask ardVideoInspectTask) {
        return ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(ardVideoInspectTask);
    }
    /**
     * 新增视频巡检任务
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int insertArdVideoInspectTask(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setCreateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setCreateTime(DateUtils.getNowDate());
        ardVideoInspectTask.setUserId(SecurityUtils.getUserId());
        int rows = ardVideoInspectTaskMapper.insertArdVideoInspectTask(ardVideoInspectTask);
        insertArdVideoInspectTaskStep(ardVideoInspectTask);
        return rows;
    }
    /**
     * 修改视频巡检任务
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int updateArdVideoInspectTask(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setUpdateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setUpdateTime(DateUtils.getNowDate());
        //  ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskId(ardVideoInspectTask.getId());
        insertArdVideoInspectTaskStep(ardVideoInspectTask);
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    /**
     * 修改视频巡检任务,bu更新步骤
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int updateArdVideoInspectTaskSingle(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setUpdateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setUpdateTime(DateUtils.getNowDate());
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    @Override
    public int updateArdVideoInspectTaskNoUpdater(ArdVideoInspectTask ardVideoInspectTask) {
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    /**
     * 批量删除视频巡检任务
     *
     * @param ids 需要删除的视频巡检任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArdVideoInspectTaskByIds(String[] ids) {
        ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskIds(ids);
        return ardVideoInspectTaskMapper.deleteArdVideoInspectTaskByIds(ids);
    }
    /**
     * 删除视频巡检任务信息
     *
     * @param id 视频巡检任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArdVideoInspectTaskById(String id) {
        ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskId(id);
        return ardVideoInspectTaskMapper.deleteArdVideoInspectTaskById(id);
    }
    /**
     * 新增视频巡检步骤信息
     *
     * @param ardVideoInspectTask 视频巡检任务对象
     */
    public void insertArdVideoInspectTaskStep(ArdVideoInspectTask ardVideoInspectTask) {
        List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTask.getArdVideoInspectTaskStepList();
        //获取相机
        ArdCameras camera = camerasMapper.selectArdCamerasById(ardVideoInspectTask.getCameraId());
        Collections.sort(ardVideoInspectTaskStepList, new ArdVideoInspectTaskStepComparator(this.ardAlarmpointsWellMapper, camera.getLongitude(), camera.getLatitude()));
        String taskId = ardVideoInspectTask.getId();
        for (int i = 0; i < ardVideoInspectTaskStepList.size(); i++) {
            ArdVideoInspectTaskStep step = ardVideoInspectTaskStepList.get(i);
            step.setTaskId(taskId);
            step.setOrderNumber(new Integer(i + 1));
        }
        if (StringUtils.isNotNull(ardVideoInspectTaskStepList)) {
            for (ArdVideoInspectTaskStep ardVideoInspectTaskStep : ardVideoInspectTaskStepList) {
                if (ardVideoInspectTaskStep.getId() == null) {
                    //新的步骤,添加
                    ardVideoInspectTaskStepMapper.insertArdVideoInspectTaskStep(ardVideoInspectTaskStep);
                } else {
                    //已有步骤,更新
                    ardVideoInspectTaskStepMapper.updateArdVideoInspectTaskStep(ardVideoInspectTaskStep);
                }
            }
        }
    }
    /**
     * 手动巡检任务
     */
    @Override
    public void manualTaskRun(String TaskId) {
        try {
            ArdVideoInspectTask videoInspectTask = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(TaskId);
            if (!videoInspectTask.getMenualSwitch().equals("开")) {
                return;
            }
            if (videoInspectTask.getArdVideoInspectTaskStepList().size() == 0) {
                return;
            }
            String currentStepId = videoInspectTask.getCurrentStepId();
            String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();
            if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                //从1号步骤开始
                videoInspectTask.setCurrentStepId(videoInspectTask.getArdVideoInspectTaskStepList().get(0).getId());
                if (InspectionTaskManager.taskMap.containsKey(TaskId)) {
                    startRunStep(videoInspectTask);
                }
            } else /*当前任务已经执行,判断是否到期*/ {
                if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                    //当前任务启动时间为null,则说明当前步骤被中断,直接启动当前步骤
                    startRunStep(videoInspectTask);
                } else {
                    boolean expird = isExpirdStep(videoInspectTask); /*判断当前步骤时间是否过期*/
                    if (expird) {
                        //停止录像
                        stopRunStep(videoInspectTask);
                        //切换步骤
                        String nextStepId = changeNextStep(videoInspectTask);
                        //开始下一步骤
                        videoInspectTask.setCurrentStepId(nextStepId);
                        startRunStep(videoInspectTask);
                    }else{
                        //未过期尝试引导,引导失败清空当前步骤开始时间,标记中断
                        tryGuide(videoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("手动巡检异常:" + ex.getMessage());
        }
    }
    /**
     * 判断当前手动任务能否开启
     */
    @Override
    public boolean isEnablemanualTask(String TaskId) {
        /*扫描当前手动开的任务,获取手动控制的相机idList*/
        List<String> menualCameraId = new ArrayList<>();
        ArdVideoInspectTask menualTask = new ArdVideoInspectTask();
        menualTask.setInspectMode("手动");
        menualTask.setMenualSwitch("开");
        List<ArdVideoInspectTask> menualTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(menualTask);
        if (menualTasks.size() > 0) {
            for (ArdVideoInspectTask task : menualTasks) {
                if (StringUtils.isNull(task.getCameraId()) || StringUtils.isEmpty(task.getCameraId())) {
                    continue;
                }
                if (!menualCameraId.contains(task.getCameraId())) {
                    menualCameraId.add(task.getCameraId());
                }
            }
        }
        /*判断相机是否已经被人手动控制*/
        ArdVideoInspectTask videoInspectTask = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(TaskId);
        if (StringUtils.isNull(videoInspectTask)) {
            return false;
        }
        String cameraId = videoInspectTask.getCameraId();
        if (StringUtils.isEmpty(cameraId)) {
            return false;
        }
        if (menualCameraId.contains(cameraId)) {
            /*如果当前任务关联的相机已经有人手动控制,则不允许控制*/
            return false;
        }
        return true;
    }
    /**
     * 自动巡检任务
     */
    @Override
    public void autoTaskRun() {
        try {
            /*扫描当前手动开的任务,获取手动控制的相机idList*/
            List<String> menualCameraId = new ArrayList<>();
            ArdVideoInspectTask menualTask = new ArdVideoInspectTask();
            menualTask.setInspectMode("手动");
            menualTask.setMenualSwitch("开");
            List<ArdVideoInspectTask> menualTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(menualTask);
            if (menualTasks.size() > 0) {
                for (ArdVideoInspectTask task : menualTasks) {
                    if (StringUtils.isNull(task.getCameraId()) || StringUtils.isEmpty(task.getCameraId())) {
                        continue;
                    }
                    if (!menualCameraId.contains(task.getCameraId())) {
                        menualCameraId.add(task.getCameraId());
                    }
                }
            }
            /*扫描所有自动任务*/
            ArdVideoInspectTask autoTask = new ArdVideoInspectTask();
            autoTask.setInspectMode("自动");
            List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(autoTask);
            for (ArdVideoInspectTask videoInspectTask : ardVideoInspectTasks) {
                /*遍历所有时间满足的自动任务*/
                boolean timeCompare = DateUtils.TimeCompare(videoInspectTask.getStartTime(), videoInspectTask.getEndTime());
                if (timeCompare) {
                    if (menualCameraId.contains(videoInspectTask.getCameraId())) {
                        /*若当前相机正在有任务手动执行,则不执行*/
                        continue;
                    }
                    /*获取当前任务的所有巡检步骤*/
                    List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(videoInspectTask.getId()).getArdVideoInspectTaskStepList();
                    if (ardVideoInspectTaskStepList.size() == 0) {
                        continue;
                    }
                    videoInspectTask.setArdVideoInspectTaskStepList(ardVideoInspectTaskStepList);
                    String currentStepId = videoInspectTask.getCurrentStepId();
                    String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();
                    if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                        //开始当前任务的第一个步骤
                        videoInspectTask.setCurrentStepId(ardVideoInspectTaskStepList.get(0).getId());
                        startRunStep(videoInspectTask);
                    } else /*当前任务已经执行,判断是否到期*/ {
                        if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                            //当前任务启动时间为空,则说明当前步骤被中断,直接启动当前步骤
                            startRunStep(videoInspectTask);
                        } else {
                            //判断当前步骤时间是否过期
                            boolean expird = isExpirdStep(videoInspectTask);
                            if (expird) {
                                //停止录像
                                stopRunStep(videoInspectTask);
                                //切换步骤
                                String nextStepId = changeNextStep(videoInspectTask);
                                //开始下一步骤
                                videoInspectTask.setCurrentStepId(nextStepId);
                                startRunStep(videoInspectTask);
                            }else{tryGuide(videoInspectTask);}
                        }
                    }
                } else {
                    if (StringUtils.isNotEmpty(videoInspectTask.getCurrentStepId())) {
                        videoInspectTask.setCurrentStepId("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(videoInspectTask);
                    }
                    if (StringUtils.isNotEmpty(videoInspectTask.getCurrentStepStartTime())) {
                        videoInspectTask.setCurrentStepId("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(videoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("自动巡检任务异常:" + ex.getMessage());
        }
    }
    /**
     * 自动手动合并,扫库方式,目前不使用
     */
    @Override
    public void taskRun() {
        ArdVideoInspectTask ardVideoInspectTask = new ArdVideoInspectTask();
        List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(ardVideoInspectTask);
        for (ArdVideoInspectTask videoInspectTask : ardVideoInspectTasks) {
            if (videoInspectTask.getInspectMode().equals("自动")) {
                boolean timeCompare = DateUtils.TimeCompare(videoInspectTask.getStartTime(), videoInspectTask.getEndTime());
                if (!timeCompare) {
                    continue;
                }
            } else {
                if (videoInspectTask.getMenualSwitch().equals("关")) {
                    continue;
                }
            }
            /*获取当前任务的所有巡检步骤*/
            List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(videoInspectTask.getId()).getArdVideoInspectTaskStepList();
            if (ardVideoInspectTaskStepList.size() == 0) {
                continue;
            }
            videoInspectTask.setArdVideoInspectTaskStepList(ardVideoInspectTaskStepList);
            String currentStepId = videoInspectTask.getCurrentStepId();//当前步骤id
            String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();//当前步骤启动时间
            if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                //开始第一个步骤
                videoInspectTask.setCurrentStepId(ardVideoInspectTaskStepList.get(0).getId());
                startRunStep(videoInspectTask);
            } else {
                if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                    //当前任务启动时间为空,则说明当前步骤被中断,直接启动当前步骤
                    startRunStep(videoInspectTask);
                } else {
                    boolean expird = isExpirdStep(videoInspectTask); /*判断当前步骤时间是否过期*/
                    if (expird) {
                        //停止录像
                        stopRunStep(videoInspectTask);
                        //切换步骤
                        String nextStepId = changeNextStep(videoInspectTask);
                        //开始下一步骤
                        videoInspectTask.setCurrentStepId(nextStepId);
                        startRunStep(videoInspectTask);
                    }
                }
            }
        }
    }
    //步骤开始
    private void startRunStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            if (StringUtils.isNull(currentStepId)) {
                log.info("当前开始巡检步骤id为空");
                return;
            }
            log.debug("巡检步骤:" + currentStepId + "尝试开始");
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                /*更新任务当前步骤id和步骤启动时间*/
                ardVideoInspectTask.setCurrentStepId(step.getId());
                ardVideoInspectTask.setCurrentStepStartTime(DateUtils.getTime());
                ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                String wellId = step.getWellId();
                if (!StringUtils.isNull(wellId)) {
                    /*获取井坐标*/
                    ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(wellId);
                    double[] targetPositon = new double[3];
                    targetPositon[0] = ardAlarmpointsWell.getLongitude();
                    targetPositon[1] = ardAlarmpointsWell.getLatitude();
                    targetPositon[2] = ardAlarmpointsWell.getAltitude();
                    /*获取相机坐标*/
                    ArdCameras cameras = ardCamerasMapper.selectArdCamerasById(cameraId);
                    double[] cameraPositon = new double[3];
                    cameraPositon[0] = cameras.getLongitude();
                    cameraPositon[1] = cameras.getLatitude();
                    cameraPositon[2] = cameras.getAltitude();
                    /*控制相机巡检*/
                    CameraCmd cmd = new CameraCmd();
                    cmd.setCameraId(cameraId);
                    cmd.setChannelNum(channel);
                    cmd.setTargetPosition(targetPositon);
                    cmd.setOperator("sys_patrol_inspect");
                    cmd.setExpired(step.getRecordingTime()*60);
                    boolean setTargetPosition = hikClientService.setTargetPosition(cmd);
                    if (setTargetPosition) {
                        /*控制相机巡检成功,开始录像*/
                        cmd.setEnable(true);//启动录像
                        hikClientService.recordToMinio(cmd);
                    } else {
                        /*控制失败,当前步骤启动时间置null*/
                        ardVideoInspectTask.setCurrentStepStartTime("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("巡检开始异常:" + ex.getMessage());
        }
    }
    //尝试控制引导
    private void tryGuide(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            if (StringUtils.isNull(currentStepId)) {
                log.info("当前开始巡检步骤id为空");
                return;
            }
            log.debug("巡检正常,尝试引导:" + currentStepId);
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                String wellId = step.getWellId();
                if (!StringUtils.isNull(wellId)) {
                    /*获取井坐标*/
                    ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(wellId);
                    double[] targetPositon = new double[3];
                    targetPositon[0] = ardAlarmpointsWell.getLongitude();
                    targetPositon[1] = ardAlarmpointsWell.getLatitude();
                    targetPositon[2] = ardAlarmpointsWell.getAltitude();
                    /*获取相机坐标*/
                    ArdCameras cameras = ardCamerasMapper.selectArdCamerasById(cameraId);
                    double[] cameraPositon = new double[3];
                    cameraPositon[0] = cameras.getLongitude();
                    cameraPositon[1] = cameras.getLatitude();
                    cameraPositon[2] = cameras.getAltitude();
                    /*控制相机巡检*/
                    CameraCmd cmd = new CameraCmd();
                    cmd.setCameraId(cameraId);
                    cmd.setChannelNum(channel);
                    cmd.setTargetPosition(targetPositon);
                    cmd.setOperator("sys_patrol_inspect");
                    cmd.setExpired(step.getRecordingTime()*60);
                    boolean setTargetPosition = hikClientService.setTargetPosition(cmd);
                    if (!setTargetPosition) {
                        /*控制失败,当前步骤启动时间置null*/
                        ardVideoInspectTask.setCurrentStepStartTime("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("巡检尝试引导异常:" + ex.getMessage());
        }
    }
    //步骤停止
    private void stopRunStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            log.debug("巡检步骤:" + currentStepId + "停止");
            if (StringUtils.isNull(currentStepId)) {
                log.info("当前停止巡检步骤id为空");
                return;
            }
            String currentStepStartTime = ardVideoInspectTask.getCurrentStepStartTime();
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                /*停止录像*/
                CameraCmd cmd = new CameraCmd();
                cmd.setCameraId(cameraId);
                cmd.setChannelNum(channel);
                cmd.setOperator("sys_patrol_inspect");
                cmd.setEnable(false);//停止录像
                String uuid = UUID.randomUUID().toString().replace("-", "");
                String time = new SimpleDateFormat("yyyyMMdd").format(new Date());
                String recordName = cameraId + "/" + time + "/" + uuid + ".mp4";
                cmd.setRecordBucketName("record");
                cmd.setRecordObjectName(recordName);
                cmd.setUploadMinio(true);
                hikClientService.recordToMinio(cmd);
                /*插入巡检记录*/
                ArdVideoInspectRecord ardVideoInspectRecord = new ArdVideoInspectRecord();
                ardVideoInspectRecord.setStepId(step.getId());
                ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(step.getWellId());
                if (StringUtils.isNotNull(ardAlarmpointsWell)) {
                    ardVideoInspectRecord.setWellName(ardAlarmpointsWell.getWellId());
                }
                Date currentStepStartDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartTime);
                Date currentStepStopDate = DateUtils.addMinutes(currentStepStartDate, step.getRecordingTime());
                ardVideoInspectRecord.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartDate));
                ardVideoInspectRecord.setEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStopDate));
                String url = MinioClientSingleton.domainUrl + "/" + cmd.getRecordBucketName() + "/" + recordName;
                ardVideoInspectRecord.setRecordFilePath(url);
                ardVideoInspectRecordMapper.insertArdVideoInspectRecord(ardVideoInspectRecord);
            }
        } catch (Exception ex) {
            log.error("巡检停止异常:" + ex.getMessage());
        }
    }
    //步骤判断是否过期
    private boolean isExpirdStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTask.getArdVideoInspectTaskStepList();
            /*获取当前任务正在执行的步骤和当前步骤开始的时间*/
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            String currentStepStartTime = ardVideoInspectTask.getCurrentStepStartTime();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTaskStepList.stream()
                    .filter(ardVideoInspectTaskStep -> ardVideoInspectTaskStep.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                /*获取当前步骤信息*/
                ArdVideoInspectTaskStep currentStep = objectOptional.get();
                /*获取到当前步骤的开始和结束时间*/
                Date currentStepStartDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartTime);
                Date currentStepStopDate = DateUtils.addMinutes(currentStepStartDate, currentStep.getRecordingTime());
                /*判断当前步骤时间是否过期*/
                if (!DateUtils.TimeCompare(currentStepStartDate, currentStepStopDate)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception ex) {
            log.error("判断巡检步骤过期异常:" + ex.getMessage());
            return false;
        }
    }
    //步骤切换
    private String changeNextStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                Integer currentStepOrderNumber = step.getOrderNumber();
                /*判断当前步骤序号是否小于步骤总数*/
                if (currentStepOrderNumber < ardVideoInspectTask.getArdVideoInspectTaskStepList().size()) {
                    /*小于则执行下一步骤*/
                    currentStepOrderNumber++;
                } else {
                    /*否则从1开始执行*/
                    currentStepOrderNumber = 1;
                }
                Integer nextStepOrderNumber = currentStepOrderNumber;
                /*更新当前任务切换新步骤*/
                ArdVideoInspectTask avit = new ArdVideoInspectTask();
                avit.setId(ardVideoInspectTask.getId());
                String nextStepId = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                        .filter(obj -> obj.getOrderNumber() == nextStepOrderNumber)
                        .map(ArdVideoInspectTaskStep::getId)
                        .findFirst()
                        .orElse(null);
                avit.setCurrentStepId(nextStepId);
                ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(avit);
                log.info("步骤:" + currentStepId + "切换为" + nextStepId);
                return nextStepId;
            }
        } catch (Exception ex) {
            log.error("巡检步骤切换异常:" + ex.getMessage());
        }
        return "";
    }
    public List getTaskUsedCameraPeriods(String cameraId) {
        return ardVideoInspectTaskMapper.getTaskUsedCameraPeriods(cameraId);
    }
    public List getCameraIdleTimeList(String cameraId) {
        LinkedList<String> timeList = new LinkedList();
        List<Map> usedPeriods = this.getTaskUsedCameraPeriods(cameraId);
        for (Map p :
                usedPeriods) {
            timeList.add((String) p.get("start_time"));
            timeList.add((String) p.get("end_time"));
        }
        //判断第一个起始点
        if (timeList.getFirst().equals("00:00:00")) {
            timeList.removeFirst();
        } else {
            timeList.addFirst("00:00:00");
        }
        //判断最后一个结束时间
        if (timeList.getLast().equals("23:59:59")) {
            timeList.removeLast();
        } else {
            timeList.addLast("23:59:59");
        }
        //事件段为空,则全天作为一个时间段
        if (timeList.size() == 0) {
            timeList.add("00:00:00");
            timeList.add("23:59:59");
        }
        return timeList;
    }
}
package com.ruoyi.inspect.service.impl;
import java.util.*;
import com.ruoyi.alarmpoints.well.domain.ArdAlarmpointsWell;
import com.ruoyi.alarmpoints.well.mapper.ArdAlarmpointsWellMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.mapper.ArdCamerasMapper;
import com.ruoyi.device.camera.service.ICameraSdkService;
import com.ruoyi.inspect.domain.ArdVideoInspectRecord;
import com.ruoyi.inspect.mapper.ArdVideoInspectRecordMapper;
import com.ruoyi.inspect.mapper.ArdVideoInspectTaskStepMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.inspect.domain.ArdVideoInspectTaskStep;
import com.ruoyi.inspect.mapper.ArdVideoInspectTaskMapper;
import com.ruoyi.inspect.domain.ArdVideoInspectTask;
import com.ruoyi.inspect.service.IArdVideoInspectTaskService;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
 * 视频巡检任务Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-30
 */
@Service
@Slf4j(topic = "patrolInspectionTask")
public class ArdVideoInspectTaskServiceImpl implements IArdVideoInspectTaskService {
    @Resource
    private ArdVideoInspectTaskMapper ardVideoInspectTaskMapper;
    @Resource
    private ArdVideoInspectTaskStepMapper ardVideoInspectTaskStepMapper;
    @Resource
    private ArdAlarmpointsWellMapper ardAlarmpointsWellMapper;
    @Resource
    private ArdVideoInspectRecordMapper ardVideoInspectRecordMapper;
    @Resource
    private ArdCamerasMapper ardCamerasMapper;
    @Resource
    private ICameraSdkService cameraSdkService;
    @Resource
    private ArdCamerasMapper camerasMapper;
    @PostConstruct
    public void initTask() {
        List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(new ArdVideoInspectTask());
        for (ArdVideoInspectTask ardVideoInspectTask : ardVideoInspectTasks) {
            /*启动后将所有手动任务置为关闭,所有任务当前步骤信息清空*/
            if (ardVideoInspectTask.getInspectMode().equals("手动")) {
                ardVideoInspectTask.setMenualSwitch("关");
            }
            ardVideoInspectTask.setCurrentStepId("");
            ardVideoInspectTask.setCurrentStepStartTime("");
            ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
        }
    }
    /**
     * 查询视频巡检任务
     *
     * @param id 视频巡检任务主键
     * @return 视频巡检任务
     */
    @Override
    public ArdVideoInspectTask selectArdVideoInspectTaskById(String id) {
        return ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(id);
    }
    /**
     * 查询视频巡检任务列表
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 视频巡检任务
     */
    @Override
    public List<ArdVideoInspectTask> selectArdVideoInspectTaskList(ArdVideoInspectTask ardVideoInspectTask) {
        return ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(ardVideoInspectTask);
    }
    /**
     * 新增视频巡检任务
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int insertArdVideoInspectTask(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setId(IdUtils.simpleUUID());
        ardVideoInspectTask.setCreateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setCreateTime(DateUtils.getNowDate());
        ardVideoInspectTask.setUserId(SecurityUtils.getUserId());
        int rows = ardVideoInspectTaskMapper.insertArdVideoInspectTask(ardVideoInspectTask);
        insertArdVideoInspectTaskStep(ardVideoInspectTask);
        return rows;
    }
    /**
     * 修改视频巡检任务
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int updateArdVideoInspectTask(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setUpdateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setUpdateTime(DateUtils.getNowDate());
        //  ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskId(ardVideoInspectTask.getId());
        insertArdVideoInspectTaskStep(ardVideoInspectTask);
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    /**
     * 修改视频巡检任务,bu更新步骤
     *
     * @param ardVideoInspectTask 视频巡检任务
     * @return 结果
     */
    @Transactional
    @Override
    public int updateArdVideoInspectTaskSingle(ArdVideoInspectTask ardVideoInspectTask) {
        ardVideoInspectTask.setUpdateBy(SecurityUtils.getUsername());
        ardVideoInspectTask.setUpdateTime(DateUtils.getNowDate());
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    @Override
    public int updateArdVideoInspectTaskNoUpdater(ArdVideoInspectTask ardVideoInspectTask) {
        return ardVideoInspectTaskMapper.updateArdVideoInspectTask(ardVideoInspectTask);
    }
    /**
     * 批量删除视频巡检任务
     *
     * @param ids 需要删除的视频巡检任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArdVideoInspectTaskByIds(String[] ids) {
        ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskIds(ids);
        return ardVideoInspectTaskMapper.deleteArdVideoInspectTaskByIds(ids);
    }
    /**
     * 删除视频巡检任务信息
     *
     * @param id 视频巡检任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArdVideoInspectTaskById(String id) {
        ardVideoInspectTaskMapper.deleteArdVideoInspectTaskStepByTaskId(id);
        return ardVideoInspectTaskMapper.deleteArdVideoInspectTaskById(id);
    }
    /**
     * 新增视频巡检步骤信息
     *
     * @param ardVideoInspectTask 视频巡检任务对象
     */
    public void insertArdVideoInspectTaskStep(ArdVideoInspectTask ardVideoInspectTask) {
        List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTask.getArdVideoInspectTaskStepList();
        //获取相机
        ArdCameras camera = camerasMapper.selectArdCamerasById(ardVideoInspectTask.getCameraId());
        Collections.sort(ardVideoInspectTaskStepList, new ArdVideoInspectTaskStepComparator(this.ardAlarmpointsWellMapper, camera.getLongitude(), camera.getLatitude()));
        String taskId = ardVideoInspectTask.getId();
        for (int i = 0; i < ardVideoInspectTaskStepList.size(); i++) {
            ArdVideoInspectTaskStep step = ardVideoInspectTaskStepList.get(i);
            step.setTaskId(taskId);
            step.setOrderNumber(new Integer(i + 1));
        }
        if (StringUtils.isNotNull(ardVideoInspectTaskStepList)) {
            for (ArdVideoInspectTaskStep ardVideoInspectTaskStep : ardVideoInspectTaskStepList) {
                if (ardVideoInspectTaskStep.getId() == null) {
                    //新的步骤,添加
                    ardVideoInspectTaskStep.setId(IdUtils.simpleUUID());
                    ardVideoInspectTaskStepMapper.insertArdVideoInspectTaskStep(ardVideoInspectTaskStep);
                } else {
                    //已有步骤,更新
                    ardVideoInspectTaskStepMapper.updateArdVideoInspectTaskStep(ardVideoInspectTaskStep);
                }
            }
        }
    }
    /**
     * 手动巡检任务
     */
    @Override
    public void manualTaskRun(String TaskId) {
        try {
            ArdVideoInspectTask videoInspectTask = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(TaskId);
            if (!videoInspectTask.getMenualSwitch().equals("开")) {
                return;
            }
            if (videoInspectTask.getArdVideoInspectTaskStepList().size() == 0) {
                return;
            }
            String currentStepId = videoInspectTask.getCurrentStepId();
            String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();
            if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                //从1号步骤开始
                videoInspectTask.setCurrentStepId(videoInspectTask.getArdVideoInspectTaskStepList().get(0).getId());
                if (InspectionTaskManager.taskMap.containsKey(TaskId)) {
                    startRunStep(videoInspectTask);
                }
            } else /*当前任务已经执行,判断是否到期*/ {
                if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                    //当前任务启动时间为null,则说明当前步骤被中断,直接启动当前步骤
                    startRunStep(videoInspectTask);
                } else {
                    boolean expird = isExpirdStep(videoInspectTask); /*判断当前步骤时间是否过期*/
                    if (expird) {
                        //停止录像
                        stopRunStep(videoInspectTask);
                        //切换步骤
                        String nextStepId = changeNextStep(videoInspectTask);
                        //开始下一步骤
                        videoInspectTask.setCurrentStepId(nextStepId);
                        startRunStep(videoInspectTask);
                    } else {
                        //未过期尝试引导,引导失败清空当前步骤开始时间,标记中断
                        tryGuide(videoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("手动巡检异常:" + ex.getMessage());
        }
    }
    /**
     * 判断当前手动任务能否开启
     */
    @Override
    public boolean isEnablemanualTask(String TaskId) {
        /*扫描当前手动开的任务,获取手动控制的相机idList*/
        List<String> menualCameraId = new ArrayList<>();
        ArdVideoInspectTask menualTask = new ArdVideoInspectTask();
        menualTask.setInspectMode("手动");
        menualTask.setMenualSwitch("开");
        List<ArdVideoInspectTask> menualTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(menualTask);
        if (menualTasks.size() > 0) {
            for (ArdVideoInspectTask task : menualTasks) {
                if (StringUtils.isNull(task.getCameraId()) || StringUtils.isEmpty(task.getCameraId())) {
                    continue;
                }
                if (!menualCameraId.contains(task.getCameraId())) {
                    menualCameraId.add(task.getCameraId());
                }
            }
        }
        /*判断相机是否已经被人手动控制*/
        ArdVideoInspectTask videoInspectTask = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(TaskId);
        if (StringUtils.isNull(videoInspectTask)) {
            return false;
        }
        String cameraId = videoInspectTask.getCameraId();
        if (StringUtils.isEmpty(cameraId)) {
            return false;
        }
        if (menualCameraId.contains(cameraId)) {
            /*如果当前任务关联的相机已经有人手动控制,则不允许控制*/
            return false;
        }
        return true;
    }
    /**
     * 自动巡检任务
     */
    @Override
    public void autoTaskRun() {
        try {
            /*扫描当前手动开的任务,获取手动控制的相机idList*/
            List<String> menualCameraId = new ArrayList<>();
            ArdVideoInspectTask menualTask = new ArdVideoInspectTask();
            menualTask.setInspectMode("手动");
            menualTask.setMenualSwitch("开");
            List<ArdVideoInspectTask> menualTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(menualTask);
            if (menualTasks.size() > 0) {
                for (ArdVideoInspectTask task : menualTasks) {
                    if (StringUtils.isNull(task.getCameraId()) || StringUtils.isEmpty(task.getCameraId())) {
                        continue;
                    }
                    if (!menualCameraId.contains(task.getCameraId())) {
                        menualCameraId.add(task.getCameraId());
                    }
                }
            }
            /*扫描所有自动任务*/
            ArdVideoInspectTask autoTask = new ArdVideoInspectTask();
            autoTask.setInspectMode("自动");
            List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(autoTask);
            for (ArdVideoInspectTask videoInspectTask : ardVideoInspectTasks) {
                /*遍历所有时间满足的自动任务*/
                boolean timeCompare = DateUtils.TimeCompare(videoInspectTask.getStartTime(), videoInspectTask.getEndTime());
                if (timeCompare) {
                    if (menualCameraId.contains(videoInspectTask.getCameraId())) {
                        /*若当前相机正在有任务手动执行,则不执行*/
                        continue;
                    }
                    /*获取当前任务的所有巡检步骤*/
                    List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(videoInspectTask.getId()).getArdVideoInspectTaskStepList();
                    if (ardVideoInspectTaskStepList.size() == 0) {
                        continue;
                    }
                    videoInspectTask.setArdVideoInspectTaskStepList(ardVideoInspectTaskStepList);
                    String currentStepId = videoInspectTask.getCurrentStepId();
                    String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();
                    if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                        //开始当前任务的第一个步骤
                        videoInspectTask.setCurrentStepId(ardVideoInspectTaskStepList.get(0).getId());
                        startRunStep(videoInspectTask);
                    } else /*当前任务已经执行,判断是否到期*/ {
                        if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                            //当前任务启动时间为空,则说明当前步骤被中断,直接启动当前步骤
                            startRunStep(videoInspectTask);
                        } else {
                            //判断当前步骤时间是否过期
                            boolean expird = isExpirdStep(videoInspectTask);
                            if (expird) {
                                //停止录像
                                stopRunStep(videoInspectTask);
                                //切换步骤
                                String nextStepId = changeNextStep(videoInspectTask);
                                //开始下一步骤
                                videoInspectTask.setCurrentStepId(nextStepId);
                                startRunStep(videoInspectTask);
                            } else {
                                tryGuide(videoInspectTask);
                            }
                        }
                    }
                } else {
                    if (StringUtils.isNotEmpty(videoInspectTask.getCurrentStepId())) {
                        videoInspectTask.setCurrentStepId("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(videoInspectTask);
                    }
                    if (StringUtils.isNotEmpty(videoInspectTask.getCurrentStepStartTime())) {
                        videoInspectTask.setCurrentStepId("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(videoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("自动巡检任务异常:" + ex.getMessage());
        }
    }
    /**
     * 自动手动合并,扫库方式,目前不使用
     */
    @Override
    public void taskRun() {
        ArdVideoInspectTask ardVideoInspectTask = new ArdVideoInspectTask();
        List<ArdVideoInspectTask> ardVideoInspectTasks = ardVideoInspectTaskMapper.selectArdVideoInspectTaskList(ardVideoInspectTask);
        for (ArdVideoInspectTask videoInspectTask : ardVideoInspectTasks) {
            if (videoInspectTask.getInspectMode().equals("自动")) {
                boolean timeCompare = DateUtils.TimeCompare(videoInspectTask.getStartTime(), videoInspectTask.getEndTime());
                if (!timeCompare) {
                    continue;
                }
            } else {
                if (videoInspectTask.getMenualSwitch().equals("关")) {
                    continue;
                }
            }
            /*获取当前任务的所有巡检步骤*/
            List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTaskMapper.selectArdVideoInspectTaskById(videoInspectTask.getId()).getArdVideoInspectTaskStepList();
            if (ardVideoInspectTaskStepList.size() == 0) {
                continue;
            }
            videoInspectTask.setArdVideoInspectTaskStepList(ardVideoInspectTaskStepList);
            String currentStepId = videoInspectTask.getCurrentStepId();//当前步骤id
            String currentStepStartTime = videoInspectTask.getCurrentStepStartTime();//当前步骤启动时间
            if (StringUtils.isNull(currentStepId) || StringUtils.isEmpty(currentStepId)) {
                //开始第一个步骤
                videoInspectTask.setCurrentStepId(ardVideoInspectTaskStepList.get(0).getId());
                startRunStep(videoInspectTask);
            } else {
                if (StringUtils.isNull(currentStepStartTime) || StringUtils.isEmpty(currentStepStartTime)) {
                    //当前任务启动时间为空,则说明当前步骤被中断,直接启动当前步骤
                    startRunStep(videoInspectTask);
                } else {
                    boolean expird = isExpirdStep(videoInspectTask); /*判断当前步骤时间是否过期*/
                    if (expird) {
                        //停止录像
                        stopRunStep(videoInspectTask);
                        //切换步骤
                        String nextStepId = changeNextStep(videoInspectTask);
                        //开始下一步骤
                        videoInspectTask.setCurrentStepId(nextStepId);
                        startRunStep(videoInspectTask);
                    }
                }
            }
        }
    }
    //步骤开始
    private void startRunStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            if (StringUtils.isNull(currentStepId)) {
                log.debug("当前开始巡检步骤id为空");
                return;
            }
            log.debug("巡检步骤:" + currentStepId + "尝试开始");
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                /*更新任务当前步骤id和步骤启动时间*/
                ardVideoInspectTask.setCurrentStepId(step.getId());
                ardVideoInspectTask.setCurrentStepStartTime(DateUtils.getTime());
                ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                String wellId = step.getWellId();
                if (!StringUtils.isNull(wellId)) {
                    /*获取井坐标*/
                    ArdAlarmpointsWell well = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(wellId);
                    double[] targetPositon = new double[3];
                    targetPositon[0] = well.getLongitude();
                    targetPositon[1] = well.getLatitude();
                    targetPositon[2] = well.getAltitude();
                    /*获取相机坐标*/
                    ArdCameras cameras = ardCamerasMapper.selectArdCamerasById(cameraId);
                    if (StringUtils.isNull(cameras)) {
                        log.debug("找不到相机:" + cameraId);
                        return;
                    }
                    double[] cameraPositon = new double[3];
                    cameraPositon[0] = cameras.getLongitude();
                    cameraPositon[1] = cameras.getLatitude();
                    cameraPositon[2] = cameras.getAltitude();
                    /*控制相机巡检*/
                    CameraCmd cmd = new CameraCmd();
                    cmd.setCameraId(cameraId);
                    cmd.setChanNo(channel);
                    cmd.setTargetPosition(targetPositon);
                    cmd.setOperator("sys_patrol_inspect");
                    cmd.setExpired(step.getRecordingTime() * 60);
                    Map<String, Double> ptzMap = new HashMap<>();
                    switch (channel) {
                        case 1:
                            ptzMap.put("p", well.getGuideP1());
                            ptzMap.put("t", well.getGuideT1());
                            ptzMap.put("z", well.getGuideZ1());
                            break;
                        case 2:
                            ptzMap.put("p", well.getGuideP2());
                            ptzMap.put("t", well.getGuideT2());
                            ptzMap.put("z", well.getGuideZ2());
                            break;
                    }
                    cmd.setPtzMap(ptzMap);
                    boolean setTargetPosition;
                    if (cmd.getPtzMap().get("p") != null) {
                        setTargetPosition = cameraSdkService.setPtz(cmd);
                    } else {
                        setTargetPosition = cameraSdkService.guideTargetPosition(cmd);
                    }
                    if (setTargetPosition) {
                        /*控制相机巡检成功,开始录像*/
                        cameraSdkService.recordStart(cmd);
                    } else {
                        /*控制失败,当前步骤启动时间置null*/
                        ardVideoInspectTask.setCurrentStepStartTime("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("巡检开始异常:" + ex.getMessage());
        }
    }
    //尝试控制引导
    private void tryGuide(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            if (StringUtils.isNull(currentStepId)) {
                log.debug("当前开始巡检步骤id为空");
                return;
            }
            log.debug("巡检正常,尝试引导:" + currentStepId);
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                String wellId = step.getWellId();
                if (!StringUtils.isNull(wellId)) {
                    /*获取井坐标*/
                    ArdAlarmpointsWell well = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(wellId);
                    double[] targetPositon = new double[3];
                    targetPositon[0] = well.getLongitude();
                    targetPositon[1] = well.getLatitude();
                    targetPositon[2] = well.getAltitude();
                    /*获取相机坐标*/
                    ArdCameras cameras = ardCamerasMapper.selectArdCamerasById(cameraId);
                    if (StringUtils.isNull(cameras)) {
                        log.debug("找不到相机:" + cameraId);
                        return;
                    }
                    double[] cameraPositon = new double[3];
                    cameraPositon[0] = cameras.getLongitude();
                    cameraPositon[1] = cameras.getLatitude();
                    cameraPositon[2] = cameras.getAltitude();
                    /*控制相机巡检*/
                    CameraCmd cmd = new CameraCmd();
                    cmd.setCameraId(cameraId);
                    cmd.setChanNo(channel);
                    cmd.setTargetPosition(targetPositon);
                    cmd.setOperator("sys_patrol_inspect");
                    cmd.setExpired(step.getRecordingTime() * 60);
                    Map<String, Double> ptzMap = new HashMap<>();
                    switch (channel) {
                        case 1:
                            ptzMap.put("p", well.getGuideP1());
                            ptzMap.put("t", well.getGuideT1());
                            ptzMap.put("z", well.getGuideZ1());
                            break;
                        case 2:
                            ptzMap.put("p", well.getGuideP2());
                            ptzMap.put("t", well.getGuideT2());
                            ptzMap.put("z", well.getGuideZ2());
                            break;
                    }
                    cmd.setPtzMap(ptzMap);
                    boolean setTargetPosition;
                    if (cmd.getPtzMap().get("p") != null) {
                        setTargetPosition = cameraSdkService.setPtz(cmd);
                    } else {
                        setTargetPosition = cameraSdkService.guideTargetPosition(cmd);
                    }
                    if (!setTargetPosition) {
                        /*控制失败,当前步骤启动时间置null*/
                        ardVideoInspectTask.setCurrentStepStartTime("");
                        ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask);
                    } else {
                        log.debug("引导成功!");
                    }
                }
            }
        } catch (Exception ex) {
            log.error("巡检尝试引导异常:" + ex.getMessage());
        }
    }
    //步骤停止
    private void stopRunStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            log.debug("巡检步骤:" + currentStepId + "停止");
            if (StringUtils.isNull(currentStepId)) {
                log.info("当前停止巡检步骤id为空");
                return;
            }
            String currentStepStartTime = ardVideoInspectTask.getCurrentStepStartTime();
            String cameraId = ardVideoInspectTask.getCameraId();
            Integer channel = ardVideoInspectTask.getChannel();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                /*停止录像*/
                CameraCmd cmd = new CameraCmd();
                cmd.setCameraId(cameraId);
                cmd.setChanNo(channel);
                cmd.setOperator("sys_patrol_inspect");
                cmd.setRecordBucketName("record");
                cmd.setRecordObjectName("inspect_" + IdUtils.fastSimpleUUID());
                String url = cameraSdkService.recordStopToMinio(cmd);
                /*插入巡检记录*/
                ArdVideoInspectRecord ardVideoInspectRecord = new ArdVideoInspectRecord();
                ardVideoInspectRecord.setId(IdUtils.simpleUUID());
                ardVideoInspectRecord.setStepId(step.getId());
                ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellById(step.getWellId());
                if (StringUtils.isNotNull(ardAlarmpointsWell)) {
                    ardVideoInspectRecord.setWellName(ardAlarmpointsWell.getWellId());
                }
                Date currentStepStartDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartTime);
                Date currentStepStopDate = DateUtils.addMinutes(currentStepStartDate, step.getRecordingTime());
                ardVideoInspectRecord.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartDate));
                ardVideoInspectRecord.setEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStopDate));
                ardVideoInspectRecord.setRecordFilePath(url);
                ardVideoInspectRecordMapper.insertArdVideoInspectRecord(ardVideoInspectRecord);
            }
        } catch (Exception ex) {
            log.error("巡检停止异常:" + ex.getMessage());
        }
    }
    //步骤判断是否过期
    private boolean isExpirdStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            List<ArdVideoInspectTaskStep> ardVideoInspectTaskStepList = ardVideoInspectTask.getArdVideoInspectTaskStepList();
            /*获取当前任务正在执行的步骤和当前步骤开始的时间*/
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            String currentStepStartTime = ardVideoInspectTask.getCurrentStepStartTime();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTaskStepList.stream()
                    .filter(ardVideoInspectTaskStep -> ardVideoInspectTaskStep.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                /*获取当前步骤信息*/
                ArdVideoInspectTaskStep currentStep = objectOptional.get();
                /*获取到当前步骤的开始和结束时间*/
                Date currentStepStartDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, currentStepStartTime);
                Date currentStepStopDate = DateUtils.addMinutes(currentStepStartDate, currentStep.getRecordingTime());
                /*判断当前步骤时间是否过期*/
                if (!DateUtils.TimeCompare(currentStepStartDate, currentStepStopDate)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception ex) {
            log.error("判断巡检步骤过期异常:" + ex.getMessage());
            return false;
        }
    }
    //步骤切换
    private String changeNextStep(ArdVideoInspectTask ardVideoInspectTask) {
        try {
            String currentStepId = ardVideoInspectTask.getCurrentStepId();
            Optional<ArdVideoInspectTaskStep> objectOptional = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                    .filter(obj -> obj.getId().equals(currentStepId))
                    .findFirst();
            if (objectOptional.isPresent()) {
                ArdVideoInspectTaskStep step = objectOptional.get();
                Integer currentStepOrderNumber = step.getOrderNumber();
                /*判断当前步骤序号是否小于步骤总数*/
                if (currentStepOrderNumber < ardVideoInspectTask.getArdVideoInspectTaskStepList().size()) {
                    /*小于则执行下一步骤*/
                    currentStepOrderNumber++;
                } else {
                    /*否则从1开始执行*/
                    currentStepOrderNumber = 1;
                }
                Integer nextStepOrderNumber = currentStepOrderNumber;
                /*更新当前任务切换新步骤*/
                ArdVideoInspectTask avit = new ArdVideoInspectTask();
                avit.setId(ardVideoInspectTask.getId());
                String nextStepId = ardVideoInspectTask.getArdVideoInspectTaskStepList().stream()
                        .filter(obj -> obj.getOrderNumber() == nextStepOrderNumber)
                        .map(ArdVideoInspectTaskStep::getId)
                        .findFirst()
                        .orElse(null);
                avit.setCurrentStepId(nextStepId);
                ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(avit);
                log.info("步骤:" + currentStepId + "切换为" + nextStepId);
                return nextStepId;
            }
        } catch (Exception ex) {
            log.error("巡检步骤切换异常:" + ex.getMessage());
        }
        return "";
    }
    public List getTaskUsedCameraPeriods(String cameraId) {
        return ardVideoInspectTaskMapper.getTaskUsedCameraPeriods(cameraId);
    }
    /**
     * 获取相机的空闲时段
     *
     * @param cameraId
     * @return
     */
    public List getCameraIdleTimeList(String cameraId) {
        LinkedList<String> timeList = new LinkedList();
        List<Map> usedPeriods = this.getTaskUsedCameraPeriods(cameraId);
        for (Map p :
                usedPeriods) {
            timeList.add((String) p.get("start_time"));
            timeList.add((String) p.get("end_time"));
        }
        //判断第一个起始点
        if (timeList.size() > 0) {
            if ("00:00:00".equals(timeList.getFirst())) {
                timeList.removeFirst();
            } else {
                timeList.addFirst("00:00:00");
            }
            //判断最后一个结束时间
            if ("23:59:59".equals(timeList.getLast())) {
                timeList.removeLast();
            } else {
                timeList.addLast("23:59:59");
            }
            //事件段为空,则全天作为一个时间段
            if (timeList.size() == 0) {
                timeList.add("00:00:00");
                timeList.add("23:59:59");
            }
        }
        return timeList;
    }
}