package com.muyu.service.impl; import com.alibaba.fastjson2.JSONArray; import com.muyu.common.pool.FixedThreadPool; import com.muyu.domain.PositionRouteInfo; import com.muyu.domain.model.PositionModel; import com.muyu.domain.model.TaskModel; import com.muyu.domain.resp.UnifiedTaskResp; import com.muyu.service.PositionRouteService; import com.muyu.service.VehicleInstanceService; import com.muyu.service.VehicleUnifiedService; import com.muyu.vehicle.VehicleInstance; import com.muyu.vehicle.core.LocalContainer; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * @author DongZeLiang * @version 1.0 * @description 一键设置业务实现层 * @date 2023/12/6 */ @Log4j2 @Service public class VehicleUnifiedServiceImpl implements VehicleUnifiedService { @Autowired private VehicleInstanceService vehicleInstanceService; @Autowired private PositionRouteService positionRouteService; /** * 任务执行模型 */ private final TaskModel taskModel = new TaskModel(); /** * 一键上线 */ @Override public void unifiedOnline () { // 获取离线车辆 List vinList = LocalContainer.getOfflineVehicleInstance().stream().map(VehicleInstance::getVin).toList(); CountDownLatch countDownLatch = new CountDownLatch(vinList.size()); // 筛选出离线车辆并使用并行流进行上线操作 for (String vin : vinList) { FixedThreadPool.submit( new Thread(() -> { try { vehicleInstanceService.vehicleClientInit(vin); taskModel.incrementSuccess(); } catch (Exception exception) { log.error("车辆上线异常:{}", exception.getMessage(), exception); taskModel.incrementError(); } countDownLatch.countDown(); }) ); } new Thread(() -> { boolean await = false; do { try { await = countDownLatch.await(5, TimeUnit.SECONDS); log.info("等待一轮训,还剩余:[{}]", countDownLatch.getCount()); } catch (InterruptedException e) { log.error("等待异常:{}", e.getMessage(), e); await = true; } } while (!await); taskModel.down(); }, "一键上线").start(); } /** * 一键离线 */ @Override public void unifiedOffline () { List onlineVehicleInstanceList = LocalContainer.getOnlineVehicleInstance(); Thread taskThread = new Thread(() -> { try { // 筛选出在线车辆使用并行流操作先停止车辆上报动作再进行车辆离线操作 onlineVehicleInstanceList .stream() .parallel() .forEach(vehicleInstance -> { try { vehicleInstance.stopSend(); vehicleInstance.closeClient(); taskModel.incrementSuccess(); }catch (Exception exception){ log.error("车辆离线异常:{}", exception.getMessage()); taskModel.incrementError(); } }); } catch (Exception exception) { log.error("车辆一键离线报错:{}", exception.getMessage(), exception); } taskModel.down(); }); // taskModel.submit("一键离线", onlineVehicleInstanceList.size(), taskThread); } /** * 一键上报 */ @Override public void unifiedSend () { List vehicleInstanceList = LocalContainer.getOnlineVehicleInstance(); if (vehicleInstanceList.isEmpty()){ throw new RuntimeException("还没有车辆连接到服务器,请先让车辆上线"); } // 获取到所有路径 List positionRouteInfoList = positionRouteService.list(); // 路径长度 int positionSize = positionRouteInfoList.size(); // 随机数 Random random = new Random(); Thread taskThread = new Thread(() -> { try { vehicleInstanceList .stream() .parallel() .forEach(vehicleInstance -> { try { // 随机一个路径结果 int positionIndex = random.nextInt(0, positionSize); PositionRouteInfo positionRouteInfo = positionRouteInfoList.get(positionIndex); String positionCode = positionRouteInfo.getName(); List positionModelList = JSONArray.parseArray(positionRouteInfo.getRouteData(), String.class) .stream() .map(PositionModel::strBuild) .toList(); // 设置车辆路径 vehicleInstance.settingPosition(positionModelList); vehicleInstance.setPositionCode(positionCode); // 设置车辆档位 vehicleInstance.setGear("D"); // 开启线程进行上报 if (vehicleInstance.getVehicleThread() == null) { vehicleInstance.initVehicleThread(); } vehicleInstance.startSend(); taskModel.incrementSuccess(); }catch (Exception exception){ log.info("车辆设置一键上报失败:{}", exception.getMessage()); taskModel.incrementError(); } }); } catch (Exception exception) { log.error("车辆一键上报报错:{}", exception.getMessage(), exception); } taskModel.down(); }); // taskModel.submit("一键上报", vehicleInstanceList.size(),taskThread); } /** * 一键重置路径 */ @Override public void unifiedPosition () { List vehicleInstanceList = LocalContainer.getOnlineVehicleInstance(); Thread taskThread = new Thread(() -> { try { // 获取到所有路径 List positionRouteInfoList = positionRouteService.list(); // 路径长度 int positionSize = positionRouteInfoList.size(); // 随机数 Random random = new Random(); vehicleInstanceList .stream() .parallel() .forEach(vehicleInstance -> { try { // 随机一个路径结果 int positionIndex = random.nextInt(0, positionSize); PositionRouteInfo positionRouteInfo = positionRouteInfoList.get(positionIndex); String positionCode = positionRouteInfo.getName(); List positionModelList = JSONArray.parseArray(positionRouteInfo.getRouteData(), String.class) .stream() .map(PositionModel::strBuild) .toList(); // 设置车辆路径 vehicleInstance.settingPosition(positionModelList); vehicleInstance.setPositionCode(positionCode); taskModel.incrementSuccess(); } catch (Exception exception) { log.error("车辆设置路线异常:[{}]", exception.getMessage()); taskModel.incrementError(); } }); } catch (Exception exception) { log.error("车辆一键重置路径报错:{}", exception.getMessage(), exception); } taskModel.down(); }); // taskModel.submit("一键重置路径",vehicleInstanceList.size(), taskThread); } /** * 一键取消上报 */ @Override public void unifiedStop () { List onlineVehicleInstanceList = LocalContainer.getOnlineVehicleInstance(); Thread taskThread = new Thread(() -> { try { LocalContainer.getOnlineVehicleInstance() .stream() .parallel() .forEach(vehicleInstance -> { try { vehicleInstance.stopSend(); taskModel.incrementSuccess(); }catch (Exception exception){ log.info("车辆一键取消上报发生错误:{}", exception.getMessage()); taskModel.incrementError(); } }); taskModel.down(); } catch (Exception exception) { log.error("车辆一键取消上报报错:{}", exception.getMessage(), exception); } }); // taskModel.submit("一键取消上报", onlineVehicleInstanceList.size(), taskThread); } /** * 一键执行状态 * * @return 一键执行状态 */ @Override public UnifiedTaskResp unifiedStatus() { boolean unifiedStatus = this.taskModel.getUnifiedStatus().get(); return UnifiedTaskResp.builder() .unifiedStatus(unifiedStatus) .taskErrorSum(this.taskModel.getErrorSum()) .taskExecutionSum(this.taskModel.getTaskExecutionSum()) .taskSuccessSum(this.taskModel.getSuccessSum()) .taskName(this.taskModel.getTaskName()) .taskStartTime(System.currentTimeMillis() - this.taskModel.getTaskStartTime()) .build(); } }