package com.gkhy.safePlatform.safeCheck.service.impl; import com.gkhy.safePlatform.account.rpc.apimodel.AccountGroupService; import com.gkhy.safePlatform.account.rpc.apimodel.model.resp.GroupRPCRespDTO; import com.gkhy.safePlatform.commons.enums.E; import com.gkhy.safePlatform.commons.exception.AusinessException; import com.gkhy.safePlatform.commons.utils.idService.SnowFlow; import com.gkhy.safePlatform.commons.vo.ResultVO; import com.gkhy.safePlatform.safeCheck.entity.*; import com.gkhy.safePlatform.safeCheck.enums.*; import com.gkhy.safePlatform.safeCheck.service.SafeCheckTaskUnitSchedulesService; import com.gkhy.safePlatform.safeCheck.service.baseService.*; import com.gkhy.safePlatform.safeCheck.util.ConsolePrintIfEnvIsDevUtil; import com.gkhy.safePlatform.safeCheck.util.timeChangeUtil; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import org.apache.dubbo.config.annotation.DubboReference; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service public class SafeCheckTaskUnitSchedulesServicelmpl implements SafeCheckTaskUnitSchedulesService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private RedissonClient redissonClient; @DubboReference(check = false) private AccountGroupService accountGroupService; @Autowired private SafeCheckWorkService safeCheckWorkService; @Autowired private SafeCheckTaskUnitService safeCheckTaskUnitService; @Autowired private SafeCheckTaskService safeCheckTaskService; @Autowired private SafeCheckQuotaService safeCheckQuotaService; @Autowired private SafeCheckPointService safeCheckPointService; @Autowired private SafeCheckRegionService safeCheckRegionService; @Autowired private SafeCheckRfidService safeCheckRfidService; @Autowired private SafeCheckUnitAndQuotaService safeCheckUnitAndQuotaService; @Autowired private SafeCheckTaskAndQuotaService safeCheckTaskAndQuotaService; /** * @description 获取未来30分钟内的开启状态的任务单元 */ @Override public List findActiveWorkListByTime() { Date startTime = new Date(); Date endTime = new Date(startTime.getTime()+ SchedulesTimeConfigEnum.SCHEDULES_SCAN_SECONDS.getSeconds()*1000); List workList = safeCheckWorkService.findActiveWorkListByTime(startTime,endTime, WorkStatusEnum.WORK_STATUS_OPEN.getStatus().intValue()); if(workList != null && workList.size() > 0){ return workList; } return null; } /** * @description 获取当前异常调度信息(下次通知时间在当前时间之前的) */ @Override public List findFaildScheduleList() { Date nowTime = new Date(); List workList = safeCheckWorkService.findFaildScheduleList(nowTime, WorkStatusEnum.WORK_STATUS_OPEN.getStatus() ,WorkStatusEnum.WORK_STATUS_DISPATCHING.getStatus()); List faildWork = new ArrayList<>(); if(workList != null && workList.size() > 0){ for (SafeCheckWork work : workList) { if (work.getWorkStatus() == 1){ faildWork.add(work); } if (work.getWorkStatus() == 4){ Date nextCheckTime = work.getNextCheckTime(); //如果当前时间超过此次调度有效时间 work状态肯定不能为调度中 Date validTime = timeChangeUtil.nextValidTime(work.getValidTime(), work.getValidTimeUnit(), nextCheckTime); if ((new Date()).compareTo(validTime) > 0){ faildWork.add(work); } } } return faildWork; } return null; } /** * @description 将任务单元work表的记录改为调度中 */ @Override public void updateWorkStatusById(SafeCheckWork work) { safeCheckWorkService.updateWorkStatusById(work, DelectStatusEnum.DELECT_NO.getStatus()); } /** * @description 根据任务单元id创建任务 */ @Transactional @Override public SafeCheckTask createAutoTask(Long workId) { ConsolePrintIfEnvIsDevUtil.consolePrintIfEnvIsDev("【##】开始创建任务----->> WORK ID:"+workId+" 【创建时间】"+new Date()); SafeCheckTask task = new SafeCheckTask(); //雪花算法生成id和uuid SnowFlow snowFlow = new SnowFlow();//雪花算法生成器 String taskUuid = UUID.randomUUID().toString(); long taskId = snowFlow.nextId(); SafeCheckWork work = safeCheckWorkService.getWorkById(workId); //0、加分布式锁 String lockName = "SAFECHECK_TASK_CREATE_"+workId; RLock createTaskLock = redissonClient.getLock(lockName); createTaskLock.lock(3, TimeUnit.SECONDS); SafeCheckTask safeCheckTask = safeCheckTaskService.getTaskByWorkIdAndTaskStartTime(workId,work.getNextCheckTime(),DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (safeCheckTask != null){ return null; } Long taskUnitId = work.getUnitId(); SafeCheckTaskUnit taskUnit = safeCheckTaskUnitService.getTaskUnitById(taskUnitId, DelectStatusEnum.DELECT_NO.getStatus().intValue()); BeanUtils.copyProperties(work,task); task.setId(taskId); task.setUuid(taskUuid); task.setUnitId(taskUnitId); task.setTaskName(taskUnit.getUnitName()); task.setExecClassgroupId(work.getExecClassgroupId()); ResultVO groupId = accountGroupService.getGroupInfoByGroupId(work.getExecClassgroupId()); if (groupId != null && groupId.getData() != null){ GroupRPCRespDTO groupRPCRespDTO = (GroupRPCRespDTO) groupId.getData(); task.setExecClassgroupName(groupRPCRespDTO.getGroupName()); } task.setPointsLength(taskUnit.getPointsLength()); task.setDeleteStatus(DelectStatusEnum.DELECT_NO.getStatus()); task.setTaskClaim(TaskClaimStatusEnum.TASK_CLAIM_STATUS_NO.getCode()); task.setTaskType(work.getWorkType()); task.setTaskStatus(TaskStatusEnum.TASK_CHECK_WAIT.getStatus()); task.setStartTime(work.getNextCheckTime()); Date nextValidTime = timeChangeUtil.nextValidTime(work.getValidTime(), work.getValidTimeUnit(), work.getNextCheckTime()); task.setValidTime(nextValidTime); task.setNoticeTime(timeChangeUtil.nextNoticeTime(work.getNoticeTime(),work.getNoticeTimeUnit(),work.getNextCheckTime())); task.setGmtCreate(new Date()); task.setCreateUserName(taskUnit.getCreateUserName()); task.setEnterpriseId(taskUnit.getEnterpriseId()); task.setEnterpriseUuid(taskUnit.getEnterpriseUuid()); task.setCheckWorkId(work.getId()); task.setCheckWorkUuid(work.getUuid()); safeCheckTaskService.saveTask(task); ConsolePrintIfEnvIsDevUtil.consolePrintIfEnvIsDev("【##】成功生成任务----->> TASK ID:"+taskId+" 【创建时间】"+new Date()); //调出这个任务单元所有的巡检链 List unitAndQuotas = safeCheckUnitAndQuotaService.listByTaskUnitId(taskUnitId, DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (unitAndQuotas == null ||unitAndQuotas.size() ==0){ throw new AusinessException(E.DATA_DATABASE_NO_EXISTENT,"该任务无相关巡检链,请添加"); } List taskAndQuotas; taskAndQuotas = unitAndQuotas.stream().map((unitAndQuota)->{ SafeCheckTaskAndQuota taskAndQuota = new SafeCheckTaskAndQuota(); BeanUtils.copyProperties(unitAndQuota,taskAndQuota,"id"); Long quotaId = unitAndQuota.getQuotaId(); SafeCheckQuota quota = safeCheckQuotaService.getQuotaById(quotaId, DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (quota != null){ taskAndQuota.setQuotaContent(quota.getQuota()); }else { taskAndQuota.setQuotaContent(null); } SafeCheckPoint point = safeCheckPointService.getOnePoint(unitAndQuota.getPointId(), DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (point != null){ taskAndQuota.setPoint(point.getCode()); }else { taskAndQuota.setPoint(null); } SafeCheckRegion region = safeCheckRegionService.getOneRegion(unitAndQuota.getRegionId(), DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (region != null){ taskAndQuota.setRegion(region.getRegion()); }else { taskAndQuota.setRegion(null); } SafeCheckRfid rfid = safeCheckRfidService.getRfidById(unitAndQuota.getRfidId(), DelectStatusEnum.DELECT_NO.getStatus().intValue()); if (rfid != null){ taskAndQuota.setRfid(rfid.getRfid()); taskAndQuota.setRfidName(rfid.getRfidName()); }else { taskAndQuota.setRfid(null); taskAndQuota.setRfidName(null); } taskAndQuota.setRfidPosition(RfidPositionEnum.RFID_POSITION_NO.getCode()); taskAndQuota.setTaskId(taskId); taskAndQuota.setTaskUuid(taskUuid); taskAndQuota.setPointCheckStatus(PointCheckStatusEnum.POINT_CHECK_STATUS_UNFINISHED.getCode()); return taskAndQuota; }).collect(Collectors.toList()); //批量将任务关联的巡检指标插入到任务指标关联表中 int saveTaskAndQuotaResult = safeCheckTaskAndQuotaService.saveTaskAndQuotas(taskAndQuotas); if (saveTaskAndQuotaResult != taskAndQuotas.size() ){ throw new AusinessException(E.ADD_FAIL,"任务关联指标插入失败"); } ConsolePrintIfEnvIsDevUtil.consolePrintIfEnvIsDev("【##】任务关联指标插入成功----->> TASK ID:"+taskId+" 【完成时间】"+new Date()); //释放分布式锁 createTaskLock.unlock(); return task; } /** * @description 变更任务状态 */ @Override public int updateTaskStatus(Long taskId, Byte taskStatus) { int updateResult = 0; //0、加分布式锁 String lockName = "SAFECHECK_MQ_TASK_STATUS_UPDATE_"+taskId+"_"+taskStatus; RLock mqUpdateTaskStatusLock = redissonClient.getLock(lockName); mqUpdateTaskStatusLock.lock(3, TimeUnit.SECONDS); SafeCheckTask safeCheckTask = safeCheckTaskService.getTaskByTaskIdAndTaskStatus(taskId,taskStatus); if (safeCheckTask != null){ return 1; } //将待巡检状态的任务转为巡检中 if (taskStatus.intValue() == 2){ updateResult = safeCheckTaskService.updateTaskStatus(taskId,taskStatus,TaskStatusEnum.TASK_CHECK_WAIT.getStatus()); } //将巡检中状态的任务转为超时未巡检 if (taskStatus.intValue() == 4){ updateResult = safeCheckTaskService.updateTaskStatus(taskId,taskStatus,TaskStatusEnum.TASK_CHECK_RUNNING.getStatus()); } //释放分布式锁 mqUpdateTaskStatusLock.unlock(); return updateResult; } /** * @description 根据任务id查询任务 */ @Override public SafeCheckTask getTaskById(Long taskId) { SafeCheckTask task = safeCheckTaskService.getTaskById(taskId); return task; } /** * @description 将work的状态由调度中改为开启状态,同时对下次通知时间、下次开始时间、上一次排查开始时间进行更新 ;如果是单次作业,直接关闭 todo */ @Transactional @Override public int resetWorkStatus(Long workId) { //0、加分布式锁 String lockName = "SAFECHECK_MQ_WORK_OPEN_STATUS_UPDATE_"+workId; RLock mqUpdateWorkOpenStatusLock = redissonClient.getLock(lockName); mqUpdateWorkOpenStatusLock.lock(3, TimeUnit.SECONDS); SafeCheckWork safeCheckWork = safeCheckWorkService.getWorkByIdAndWorkStatus(workId,WorkStatusEnum.WORK_STATUS_DISPATCHING.getStatus()); if (safeCheckWork == null){ return 1; } SafeCheckWork work = safeCheckWorkService.getWorkById(workId); Date checkTime = work.getNextCheckTime(); work.setLastCheckTime(checkTime); int updateResult = 0; if (work.getWorkType() == WorkTypeEnum.WORK_TYPE_DAILY.getCode()) { work.setNextCheckTime(null); work.setNextNoticeTime(null); updateResult = safeCheckWorkService.resetWorkStatus(work, WorkStatusEnum.WORK_STATUS_CLOSE.getStatus()); //单次任务同时也要把任务关闭 SafeCheckTaskUnit taskUnit = new SafeCheckTaskUnit(); taskUnit.setId(work.getUnitId()); taskUnit.setTaskUnitStatus(TaskUnitStatusEnum.TASK_UNIT_STATUS_CLOSE.getStatus()); safeCheckTaskUnitService.updateTaskUniStatusById(taskUnit,DelectStatusEnum.DELECT_NO.getStatus()); }else { Date nextCheckTime = timeChangeUtil.nextCheckTime(work.getCheckCycle(), work.getCheckCycleUnit(),checkTime); Date nextNoticeTime = timeChangeUtil.nextNoticeTime(work.getNoticeTime(), work.getNoticeTimeUnit(), nextCheckTime); work.setNextCheckTime(nextCheckTime); work.setNextNoticeTime(nextNoticeTime); updateResult = safeCheckWorkService.resetWorkStatus(work, WorkStatusEnum.WORK_STATUS_OPEN.getStatus()); } //释放分布式锁 mqUpdateWorkOpenStatusLock.unlock(); return updateResult; } /** * @description 对于通知时间在当前时间之前的调度信息 将通知时间更改为当前时间之后的十分钟 */ @Override public int resetScheduleTime(Long id, Date newNoticeTime) { SafeCheckWork work = safeCheckWorkService.getWorkById(id); Date lastCheckTime = work.getNextCheckTime(); Date nextCheckTime= timeChangeUtil.getNextCheckTimeByNextNoticeTime(work.getNoticeTime(), work.getNoticeTimeUnit(), newNoticeTime); work.setNextNoticeTime(newNoticeTime); work.setNextCheckTime(nextCheckTime); work.setLastCheckTime(lastCheckTime); int updateResult = safeCheckWorkService.resetWorkStatus(work, TaskUnitStatusEnum.TASK_UNIT_STATUS_OPEN.getStatus()); return updateResult; } }