package com.maibu.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.maibu.core.business.*; import com.maibu.core.business.device.NettyDevice; import com.maibu.core.domain.entity.SysSite; import com.maibu.core.domain.model.LoginUser; import com.maibu.core.enums.DeviceTaskStaus; import com.maibu.dto.*; import com.maibu.manager.DeviceSessionManager; import com.maibu.mapper.*; import com.maibu.memory.GlobalMemory; import com.maibu.memory.SiteMemory; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Random; import java.util.stream.Collectors; @Service @Slf4j public class DeviceTaskService { @Autowired private DevicePlanMapper devicePlanMapper; @Autowired private DevicePlanTaskMapper devicePlanTaskMapper; @Autowired private DeviceMapper deviceMapper; @Autowired private WorkRecordMapper workRecordMapper; @Autowired private DeviceSessionManager deviceSessionManager; @Autowired private SysSiteMapper sysSiteMapper; public int insertOrUpdate(DevicePlan devicePlan, LoginUser loginUser) { Long id = devicePlan.getId(); SiteMemory siteMemory = GlobalMemory.getSiteMemory(devicePlan.getOrgId(), devicePlan.getSiteId()); if (id != null) { devicePlan.setUpdateBy(loginUser.getUsername()); devicePlan.setUpdateTime(LocalDateTime.now()); transferDays(devicePlan); int i = devicePlanMapper.updateById(devicePlan); siteMemory.addDevicePlan(devicePlan); return i; } else { devicePlan.setTaskStaus(DeviceTaskStaus.NEW); devicePlan.setCreateTime(LocalDateTime.now()); devicePlan.setCreateBy(loginUser.getUsername()); transferDays(devicePlan); int i = devicePlanMapper.insert(devicePlan); siteMemory.addDevicePlan(devicePlan); return i; } } public void transferDays(DevicePlan devicePlan) { DeviceTaskPlanRule deviceTaskPlanRules = devicePlan.getDeviceTaskPlanRules(); if (deviceTaskPlanRules != null && !CollectionUtils.isEmpty(deviceTaskPlanRules.getDays())) { List days = new ArrayList<>(); deviceTaskPlanRules.getDays().forEach(x -> { String day = null; switch (x) { case MONDAY: day = "周一"; break; case TUESDAY: day = "周二"; break; case WEDNESDAY: day = "周三"; break; case THURSDAY: day = "周四"; break; case FRIDAY: day = "周五"; break; case SATURDAY: day = "周六"; break; case SUNDAY: day = "周日"; break; } days.add(day); }); devicePlan.getDeviceTaskPlanRules().setDaysTranslate(days); } } public List getDeviceTaskByUser(Long userId) { if (userId != null) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DevicePlan::getUserId, userId); return transferDevicePlanData(devicePlanMapper.selectList(queryWrapper)); } else { return new ArrayList<>(); } } public List getSiteDevicePlan(Long siteId, LocalDate startTime, LocalDate endTime, String deviceId, DeviceTaskStaus taskStaus) { if (siteId != null) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DevicePlan::getSiteId, siteId); if (taskStaus != null) { queryWrapper.eq(DevicePlan::getTaskStaus, taskStaus); } if (!StringUtils.isEmpty(deviceId)) { queryWrapper.eq(DevicePlan::getDeviceId, deviceId); } if (startTime != null && endTime != null) { queryWrapper.between(DevicePlan::getCreateTime, startTime, endTime); } return transferDevicePlanData(devicePlanMapper.selectList(queryWrapper)); } else { return new ArrayList<>(); } } public List getDeviceTask(DeviceTaskQueryDTO dto) { if (dto != null) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (dto.getUserId() != null) { queryWrapper.eq(DevicePlan::getUserId, dto.getUserId()); } if (!StringUtils.isEmpty(dto.getDeviceId())) { queryWrapper.eq(DevicePlan::getDeviceId, dto.getDeviceId()); } if (dto.getTaskStaus() != null) { queryWrapper.eq(DevicePlan::getTaskStaus, dto.getTaskStaus()); } if (dto.getOrgId() != null) { queryWrapper.eq(DevicePlan::getOrgId, dto.getOrgId()); } if (dto.getSiteId() != null) { queryWrapper.eq(DevicePlan::getSiteId, dto.getSiteId()); } if (!StringUtils.isEmpty(dto.getPlanName())) { queryWrapper.like(DevicePlan::getPlanName, dto.getPlanName()); } queryWrapper.eq(DevicePlan::getDelFlag, 0); List list = devicePlanMapper.selectList(queryWrapper); if (!CollectionUtils.isEmpty(list)) { list.forEach(x -> { Device device = deviceMapper.selectDeviceBySerialNumber(x.getDeviceId()); if (device != null) { x.setDeviceAlias(device.getDeviceAlias()); } }); } return transferDevicePlanData(list); } else { return new ArrayList<>(); } } public int delete(Long id) { DevicePlan planTask = devicePlanMapper.selectById(id); if (planTask != null) { if (planTask.getOrgId() == null) { SysSite site = sysSiteMapper.selectById(planTask.getSiteId()); if (site != null) { planTask.setOrgId(site.getOrgId()); } } SiteMemory siteMemory = GlobalMemory.getSiteMemory(planTask.getOrgId(), planTask.getSiteId()); if (siteMemory != null) { siteMemory.removeDevicePlan(planTask); } return devicePlanMapper.deleteById(id); } return 0; } public void start(Long id, LoginUser loginUser) { if (id != null) { DevicePlan planTask = devicePlanMapper.selectById(id); if (planTask != null) { planTask.setTaskStaus(DeviceTaskStaus.EXECUTING); planTask.setUpdateTime(LocalDateTime.now()); planTask.setUpdateBy(loginUser.getUsername()); devicePlanMapper.updateById(planTask); } } } public List getDevicePlanStatistics(Long userId) { List list = new ArrayList<>(); LocalDate today = LocalDate.now(); LocalDateTime monthStart = LocalDateTime.of( today.getYear(), // 当前年 today.getMonth(), // 当前月 1, // 当月第一天 0, 0, 0, 0 // 时:分:秒:纳秒(00:00:00.000) ); LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth()); // 获取当月最后一天 LocalDateTime monthEnd = LocalDateTime.of( lastDayOfMonth.getYear(), lastDayOfMonth.getMonth(), lastDayOfMonth.getDayOfMonth(), 23, 59, 59, 999_999_999 // 时:分:秒:纳秒(23:59:59.999) ); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(DevicePlan::getCreateTime, monthStart) .le(DevicePlan::getCreateTime, monthEnd) .eq(DevicePlan::getUserId, userId); List devicePlans = transferDevicePlanData(devicePlanMapper.selectList(queryWrapper)); if (!CollectionUtils.isEmpty(devicePlans)) { List dates = getMonthDays(); for (LocalDate date : dates) { List plans = devicePlans.stream().filter(x -> x.getCreateTime().toLocalDate().equals(date)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(plans)) { DevicePlanStatisticsDTO dto = new DevicePlanStatisticsDTO(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M.d"); dto.setName(formatter.format(date)); long count = plans.stream().filter(x -> DeviceTaskStaus.FINISH.equals(x.getTaskStaus())).count(); dto.setCompleted((int) count); dto.setPlanned(plans.size()); list.add(dto); } } } return list; } public List getMonthDays() { LocalDate today = LocalDate.now(); int totalDays = today.lengthOfMonth(); LocalDate firstDayOfMonth = LocalDate.of(today.getYear(), today.getMonth(), 1); List allDaysOfCurrentMonth = new ArrayList<>(); for (int i = 0; i < totalDays; i++) { // 每次累加1天,获取当月每一天 LocalDate currentDay = firstDayOfMonth.plusDays(i); allDaysOfCurrentMonth.add(currentDay); } return allDaysOfCurrentMonth; } public List getDevicePlanTaskStatistics(Long userId) { List list = new ArrayList<>(); // 1. 获取当前日期 LocalDate today = LocalDate.now(); // 2. 构造当前月份的起始时间:当月第一天 00:00:00 LocalDateTime monthStart = LocalDateTime.of( today.getYear(), // 当前年 today.getMonth(), // 当前月 1, // 当月第一天 0, 0, 0, 0 // 时:分:秒:纳秒(00:00:00.000) ); // 3. 构造当前月份的结束时间:当月最后一天 23:59:59.999 LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth()); // 获取当月最后一天 LocalDateTime monthEnd = LocalDateTime.of( lastDayOfMonth.getYear(), lastDayOfMonth.getMonth(), lastDayOfMonth.getDayOfMonth(), 23, 59, 59, 999_999_999 // 时:分:秒:纳秒(23:59:59.999) ); // 4. 构建 LambdaQueryWrapper 进行范围查询 LambdaQueryWrapper query = new LambdaQueryWrapper<>(); query.eq(DevicePlan::getUserId, userId); List devicePlans = transferDevicePlanData(devicePlanMapper.selectList(query)); if (CollectionUtils.isEmpty(devicePlans)) return new ArrayList<>(); List planIds = devicePlans.stream().map(DevicePlan::getId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(planIds)) return new ArrayList<>(); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); // 核心:筛选 createTime 大于等于起始时间,且小于等于结束时间 queryWrapper.ge(DevicePlanTask::getCreateTime, monthStart) .le(DevicePlanTask::getCreateTime, monthEnd) .in(DevicePlanTask::getPlanId, planIds); List devicePlanTasks = transferDeviceTaskData(devicePlanTaskMapper.selectList(queryWrapper)); if (!CollectionUtils.isEmpty(devicePlanTasks)) { List dates = getMonthDays(); for (LocalDate date : dates) { List planTasks = devicePlanTasks.stream().filter(x -> x.getCreateTime().toLocalDate().equals(date)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(planTasks)) { DevicePlanTaskStatisticsDTO dto = new DevicePlanTaskStatisticsDTO(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M.d"); dto.setDate(formatter.format(date)); long finishCount = planTasks.stream().filter(x -> DeviceTaskStaus.FINISH.equals(x.getTaskStaus())).count(); dto.setSuccess((int) finishCount); long failedCount = planTasks.stream().filter(x -> DeviceTaskStaus.FAILED.equals(x.getTaskStaus())).count(); dto.setFailed((int) failedCount); long pauseCount = planTasks.stream().filter(x -> DeviceTaskStaus.PAUSE.equals(x.getTaskStaus())).count(); dto.setPaused((int) pauseCount); list.add(dto); } } } return list; } public WorkRecord concurrentDevicePlanTask(String deviceId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DevicePlanTask::getDeviceId, deviceId) .eq(DevicePlanTask::getTaskStaus, DeviceTaskStaus.EXECUTING); List devicePlanTasks = devicePlanTaskMapper.selectList(queryWrapper); Long routId = CollectionUtils.isEmpty(devicePlanTasks) ? null : devicePlanTasks.get(0).getRouteId(); return routId == null ? null : workRecordMapper.selectById(routId); } public List workStatistics(Long userId) { //todo update List result = new ArrayList<>(); Random random = new Random(); int times = random.nextInt(100); int s = random.nextInt(1000); DeviceWorkStatisticsDTO dto = new DeviceWorkStatisticsDTO(); dto.setLabel("割草次数"); dto.setValue(times); DeviceWorkStatisticsDTO dto2 = new DeviceWorkStatisticsDTO(); dto2.setLabel("割草时长(s)"); dto2.setValue(s); DeviceWorkStatisticsDTO dto3 = new DeviceWorkStatisticsDTO(); dto3.setLabel("割草面积(m2)"); dto3.setValue(s * 5); result.add(dto); result.add(dto2); result.add(dto3); return result; } public List deviceTaskPool(DeviceTaskQueryDTO dto) { List list = new ArrayList<>(); if (dto.getOrgId() == null) { SysSite site = sysSiteMapper.selectById(dto.getSiteId()); if (site != null) { dto.setOrgId(site.getOrgId()); } } SiteMemory siteMemory = GlobalMemory.getSiteMemory(dto.getOrgId(), dto.getSiteId()); siteMemory.devicePlanTaskPrepareMap.values().forEach(list::addAll); list.addAll(SiteMemory.devicePlanTaskExecuteMap.values()); if (dto.getTaskStaus() != null) { list = list.stream().filter(x -> x.getTaskStaus().equals(dto.getTaskStaus())).collect(Collectors.toList()); } if (!StringUtils.isEmpty(dto.getDeviceId())) { list = list.stream().filter(x -> x.getDeviceId().equals(dto.getDeviceId())).collect(Collectors.toList()); } if (dto.getPlanId() != null) { list = list.stream().filter(x -> x.getPlanId().equals(dto.getPlanId())).collect(Collectors.toList()); } if (dto.getSiteId() != null) { list = list.stream().filter(x -> x.getSiteId().equals(dto.getSiteId())).collect(Collectors.toList()); } if (dto.getOrgId() != null) { list = list.stream().filter(x -> x.getOrgId().equals(dto.getOrgId())).collect(Collectors.toList()); } if (!StringUtils.isEmpty(dto.getDeviceId())) { list = list.stream().filter(x -> x.getDeviceId().equals(dto.getDeviceId())).collect(Collectors.toList()); } return transferDeviceTaskData(list); } public List getSiteDeviceTaskHistory(DeviceTaskQueryDTO dto) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (dto.getSiteId() != null) { queryWrapper.eq(DevicePlanTask::getSiteId, dto.getSiteId()); } if (dto.getOrgId() != null) { queryWrapper.eq(DevicePlanTask::getOrgId, dto.getOrgId()); } if (dto.getTaskStaus() != null) { queryWrapper.eq(DevicePlanTask::getTaskStaus, dto.getTaskStaus()); } if (dto.getPlanId() != null) { queryWrapper.eq(DevicePlanTask::getPlanId, dto.getPlanId()); } if (!StringUtils.isEmpty(dto.getDeviceId())) { queryWrapper.eq(DevicePlanTask::getDeviceId, dto.getDeviceId()); } return transferDeviceTaskData(devicePlanTaskMapper.selectList(queryWrapper)); } public List transferDevicePlanData(List list) { if (CollectionUtils.isEmpty(list)) return list; list.forEach(x -> { DeviceTaskStaus taskStaus = x.getTaskStaus(); x.setTaskStausTranslate(taskStaus.getDescription()); }); return list; } public List transferDeviceTaskData(List list) { if (CollectionUtils.isEmpty(list)) return list; list.forEach(x -> { DeviceTaskStaus taskStaus = x.getTaskStaus(); x.setTaskStausTranslate(taskStaus.getDescription()); }); return list; } public boolean createDeviceTask(DeviceTaskCommandDTO dto, String username) { DevicePlanTask task = new DevicePlanTask(); task.setOrgId(dto.getOrgId()); task.setSiteId(dto.getSiteId()); task.setTaskStaus(DeviceTaskStaus.NEW); task.setDeviceId(dto.getDeviceId()); task.setCreateBy(username); task.setCreateTime(LocalDateTime.now()); task.setRouteId(dto.getRouteId()); task.setStartTime(dto.getStartTime()); boolean result = devicePlanTaskMapper.saveOrUpdate(task); if (dto.getOrgId() == null) { SysSite site = sysSiteMapper.selectById(dto.getSiteId()); if (site != null) { dto.setOrgId(site.getOrgId()); } } SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId()); siteMemory.addDevicePlanPrepare(task); return result; } public boolean cancelTask(DeviceTaskCommandDTO dto, String username) { if (!StringUtils.isEmpty(dto.getDeviceId())) { NettyDevice device = deviceSessionManager.getDevice(dto.getDeviceId()); if (device != null) { return device.cancelTask(); } } else { Long taskId = dto.getTaskId(); // Long siteId = dto.getSiteId(); // Long orgId = dto.getOrgId(); DevicePlanTask devicePlanTask = devicePlanTaskMapper.selectById(taskId); if (devicePlanTask != null) { NettyDevice device = deviceSessionManager.getDevice(devicePlanTask.getDeviceId()); if (device != null) { return device.cancelTask(); } } } return false; } //todo 完善 public boolean pauseTask(DeviceTaskCommandDTO dto, String username) { if (!StringUtils.isEmpty(dto.getDeviceId())) { NettyDevice device = deviceSessionManager.getDevice(dto.getDeviceId()); if (device != null) { return device.pauseTask(); } } else { Long taskId = dto.getTaskId(); DevicePlanTask devicePlanTask = devicePlanTaskMapper.selectById(taskId); if (devicePlanTask != null) { devicePlanTask.setUpdateTime(LocalDateTime.now()); devicePlanTask.setTaskStaus(DeviceTaskStaus.PAUSE); devicePlanTask.setUpdateBy(username); devicePlanTaskMapper.saveOrUpdate(devicePlanTask); } } return false; } //todo 完善 public boolean recoveryTask(DeviceTaskCommandDTO dto, String username) { if (!StringUtils.isEmpty(dto.getDeviceId())) { NettyDevice device = deviceSessionManager.getDevice(dto.getDeviceId()); if (device != null) { return device.recoveryTask(); } } else { Long taskId = dto.getTaskId(); Long siteId = dto.getSiteId(); Long orgId = dto.getOrgId(); DevicePlanTask devicePlanTask = devicePlanTaskMapper.selectById(taskId); SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId); DevicePlanTask executeTask = siteMemory.getDeviceExecuteTask(devicePlanTask.getDeviceId()); if (Objects.equals(devicePlanTask.getId(), executeTask.getId())) { devicePlanTask.setUpdateTime(LocalDateTime.now()); devicePlanTask.setTaskStaus(DeviceTaskStaus.EXECUTING); devicePlanTask.setUpdateBy(username); devicePlanTaskMapper.saveOrUpdate(devicePlanTask); } } return false; } }