diff --git a/zc-business/src/main/java/com/zc/business/constant/DeviceFunctionIdConstants.java b/zc-business/src/main/java/com/zc/business/constant/DeviceFunctionIdConstants.java new file mode 100644 index 00000000..e8a097e2 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/constant/DeviceFunctionIdConstants.java @@ -0,0 +1,21 @@ +package com.zc.business.constant; + +/** + * 设备-功能id常量 + * @author wangjiabao + */ +public class DeviceFunctionIdConstants { + + /** + * 行车诱导 + */ + public static final String DRIVING_GUIDANCE = "51"; + /** + * 摄像机 + */ + public static final String CAMERA = "51"; + /** + * 可变信息标志 + */ + public static final String VARIABLE_INFORMATION_FLAG = "1B"; +} diff --git a/zc-business/src/main/java/com/zc/business/constant/DeviceTypeConstants.java b/zc-business/src/main/java/com/zc/business/constant/DeviceTypeConstants.java new file mode 100644 index 00000000..5ad05ab9 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/constant/DeviceTypeConstants.java @@ -0,0 +1,80 @@ +package com.zc.business.constant; + +/** + * 设备类型常量 + * @author wangjiabao + */ +public class DeviceTypeConstants { + + /** + * 摄像机 + */ + public static final Integer CAMERA = 1; + + /** + * 可变信息标志 + */ + public static final Integer VARIABLE_INFORMATION_FLAG = 2; + + /** + * 气象检测器 + */ + public static final Integer METEOROLOGICAL_DETECTOR = 3; + + /** + * 出口诱导灯 + */ + public static final Integer EXPORT_INDUCTION_LIGHT = 4; + + /** + * 路段语音广播 + */ + public static final Integer ROAD_SECTION_VOICE_BROADCASTING = 5; + + /** + * 护栏碰撞 + */ + public static final Integer COLLISION_OF_GUARDRAILS = 6; + + /** + * 毫米波雷达 + */ + public static final Integer MILLIMETER_WAVE_RADAR = 7; + + /** + * 合流区预警 + */ + public static final Integer CONFLUENCE_AREA_WARNING = 8; + + /** + * 智慧锥桶 + */ + public static final Integer SMART_CONE_BUCKET = 9; + + /** + * 激光疲劳唤醒 + */ + public static final Integer LASER_FATIGUE_AWAKENING = 10; + + /** + * 一类交流站 + */ + public static final Integer CLASS_I_COMMUNICATION_STATION = 11; + + /** + * 行车诱导 + */ + public static final Integer DRIVING_GUIDANCE = 12; + + /** + * 智能设备箱 + */ + public static final Integer SMART_DEVICE_BOX = 13; + + /** + * 光线在线监测 + */ + public static final Integer ONLINE_MONITORING_OF_LIGHT = 14; + + +} diff --git a/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java b/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java index 789ad59e..968fa59f 100644 --- a/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java +++ b/zc-business/src/main/java/com/zc/business/controller/DcEmergencyPlansController.java @@ -5,6 +5,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.zc.business.domain.DcEmergencyPlans; import com.zc.business.domain.DcEvent; +import com.zc.business.domain.DcEventAnDcEmergencyPlans; import com.zc.business.service.DcEmergencyPlansService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -12,7 +13,6 @@ import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; - import java.util.List; /** @@ -65,6 +65,16 @@ public class DcEmergencyPlansController extends BaseController { return AjaxResult.success(dcEmergencyPlansList); } + /** + * 事件确定 + */ + @ApiOperation("事件确认") + @PreAuthorize("@ss.hasPermi('business:plans:edit')") + @PostMapping("/event/confirm") + public AjaxResult EventConfirm(@RequestBody DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { + return toAjax(dcEmergencyPlansService.executionEventConfirmation(dcEventAnDcEmergencyPlans)); + } + /** * 新增事件预案 */ diff --git a/zc-business/src/main/java/com/zc/business/domain/DcEventAnDcEmergencyPlans.java b/zc-business/src/main/java/com/zc/business/domain/DcEventAnDcEmergencyPlans.java new file mode 100644 index 00000000..98d8cb32 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/DcEventAnDcEmergencyPlans.java @@ -0,0 +1,39 @@ +package com.zc.business.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 事件数据和事件预案数据 + * + * @author wangjiabao + * @date 2024-02-27 + */ + +@ApiModel("事件数据和事件预案数据") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DcEventAnDcEmergencyPlans { + + /** + * 事件数据 + */ + @ApiModelProperty("事件数据") + private DcEvent dcEvent; + + /** + * 事件预案数据 + */ + @ApiModelProperty("事件预案数据") + private DcEmergencyPlans dcEmergencyPlans; + + /** + * 操作类型 1-执行操作 2-恢复操作 + */ + @ApiModelProperty("操作类型") + private Integer operationType; +} diff --git a/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java b/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java new file mode 100644 index 00000000..162d32e4 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/domain/EventPlanAssoc.java @@ -0,0 +1,66 @@ +package com.zc.business.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 预案事件关联对象 event_plan_assoc + * + * @author wangjiabao + * @date 2024-02-27 + */ + +@ApiModel("预案事件关联实体") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EventPlanAssoc { + + @ApiModelProperty("预案事件关联id") + private String id; + /** + * 所属事件编号 + */ + @ApiModelProperty("所属事件编号") + private String eventId; + + /** + * 所属预案编号 + */ + @ApiModelProperty("所属预案编号") + private Integer emergencyPlansId; + + /** + * 执行控制设备 (设备id用逗号隔开) + */ + @ApiModelProperty("执行控制设备") + private String executingControlDevice; + + /** + * 恢复控制设备 (设备id用逗号隔开) + */ + @ApiModelProperty("恢复控制设备") + private String recoveredControlDevice; + + @ApiModelProperty("创建时间") + private Date createTime; + @ApiModelProperty("修改时间") + private Date updateTime; + + /** + * 执行操作结果 + */ + @ApiModelProperty("执行操作结果") + private String executingControlResult; + + /** + * 恢复操作结果 + */ + @ApiModelProperty("恢复操作结果") + private String recoveredControlResult; +} diff --git a/zc-business/src/main/java/com/zc/business/mapper/EventPlanAssocMapper.java b/zc-business/src/main/java/com/zc/business/mapper/EventPlanAssocMapper.java new file mode 100644 index 00000000..15c13da3 --- /dev/null +++ b/zc-business/src/main/java/com/zc/business/mapper/EventPlanAssocMapper.java @@ -0,0 +1,35 @@ +package com.zc.business.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zc.business.domain.EventPlanAssoc; +import org.apache.ibatis.annotations.Mapper; + +/** + * 预案事件关联Mapper接口 + * + * @author wangjiabao + */ +@Mapper +public interface EventPlanAssocMapper extends BaseMapper { + + /** + * 新增事件预案关联 + * @param eventPlanAssoc + * @return + */ + int insertEventPlanAssoc(EventPlanAssoc eventPlanAssoc); + + /** + * 根据事件id查询事件预案关联 + * @param eventPlanAssoc + * @return + */ + EventPlanAssoc selectByEventId(EventPlanAssoc eventPlanAssoc); + + /** + * 修改事件预案关联 + * @param eventPlanAssoc + * @return + */ + int updateEventPlanAssoc(EventPlanAssoc eventPlanAssoc); +} diff --git a/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java b/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java index 60ac1997..8001d3b3 100644 --- a/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java +++ b/zc-business/src/main/java/com/zc/business/service/DcEmergencyPlansService.java @@ -2,7 +2,7 @@ package com.zc.business.service; import com.zc.business.domain.DcEmergencyPlans; import com.zc.business.domain.DcEvent; - +import com.zc.business.domain.DcEventAnDcEmergencyPlans; import java.util.List; /** @@ -33,11 +33,19 @@ public interface DcEmergencyPlansService { /** * 根据事件类型查询事件预案 * - * @param event 事件预案 + * @param event 事件 * @return 结果 */ List selectDcEmergencyPlansByEventType(DcEvent event); + /** + * 事件确定 + * + * @param dcEventAnDcEmergencyPlans 事件数据 和 事件预案数据 + * @return 结果 + */ + int executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans); + /** * 新增事件预案 * diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java index a132b91a..625b4637 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcEmergencyPlansServiceImpl.java @@ -3,14 +3,22 @@ package com.zc.business.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.DateUtils; +import com.zc.business.constant.DeviceFunctionIdConstants; +import com.zc.business.constant.DeviceTypeConstants; +import com.zc.business.controller.DcDeviceController; import com.zc.business.domain.*; import com.zc.business.enums.EventTypeEnum; import com.zc.business.mapper.DcEmergencyPlansMapper; +import com.zc.business.mapper.EventPlanAssocMapper; import com.zc.business.service.DcEmergencyPlansService; import com.zc.business.service.DcExecuteActionService; +import com.zc.business.service.IDcDeviceService; +import com.zc.common.core.httpclient.exception.HttpException; import org.apache.commons.lang3.StringEscapeUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,6 +27,8 @@ import javax.annotation.Resource; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -29,6 +39,12 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { private DcEmergencyPlansMapper dcEmergencyPlansMapper; @Resource private DcExecuteActionService dcExecuteActionService; + @Resource + private IDcDeviceService dcDeviceService; + @Resource + private DcDeviceController dcDeviceController; + @Resource + private EventPlanAssocMapper eventPlanAssocMapper; /** @@ -56,7 +72,7 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { /** * 根据事件类型查询事件预案 * - * @param event 事件预案 + * @param event 事件 * @return 结果 */ @Override @@ -208,6 +224,214 @@ public class DcEmergencyPlansServiceImpl implements DcEmergencyPlansService { } + /** + * 事件确定 + * + * @param dcEventAnDcEmergencyPlans 事件数据 和 事件预案数据 + * @return 结果 + */ + @Override + public int executionEventConfirmation(DcEventAnDcEmergencyPlans dcEventAnDcEmergencyPlans) { + + // 存储所有设备id + StringBuilder deviceIds = new StringBuilder(); + // 存储所有设备的执行结果 + JSONArray resultArray = new JSONArray(); + + // 获取事件数据 + DcEvent dcEvent = dcEventAnDcEmergencyPlans.getDcEvent(); + // 获取事件预案数据 + DcEmergencyPlans dcEmergencyPlans = dcEventAnDcEmergencyPlans.getDcEmergencyPlans(); + // 事件桩号 + String[] markArray = dcEvent.getStakeMark().split("\\+"); + if (markArray[1].length() < 3) { + // 不足三位 补零 + markArray[1] = String.format("%0" + 3 + "d", markArray[1]); + } + // 方向 + String direction = dcEvent.getDirection(); + + //获取事件预案中的 执行操作配置 + dcEmergencyPlans.getDcExecuteAction().stream() + .forEach(dcExecuteAction -> { + Integer searchRule = dcExecuteAction.getSearchRule(); + List start = new ArrayList<>(); + List end = new ArrayList<>(); + // 设备列表 + List dcDevices = new ArrayList<>(); + Map parameter = new HashMap<>(); + parameter.put("deviceType", dcExecuteAction.getDeviceType()); + // 根据不同的检索规则条件 获取设备 + if (searchRule.equals(1)) { + // 指定设备资源 + // 根据设备id,获取设备集合 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + JSONObject otherConfig = JSON.parseObject(dcExecuteAction.getOtherConfig()); + JSONArray deviceList = JSONArray.parseArray(otherConfig.get("deviceList").toString()); + queryWrapper.in(DcDevice::getId, deviceList); + dcDevices = dcDeviceService.list(queryWrapper); + } else if (searchRule.equals(2)) { + + // 事件上游最近 + if (direction.equals("1")) { + // 上行 取最大的几个 + start.add("55"); + start.add("378.7"); + end.add(markArray[0]); + end.add(markArray[1]); + parameter.put("startStakeMark", start); + parameter.put("endStakeMark", end); + dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + dcDevices = dcDevices.subList(dcDevices.size() - dcExecuteAction.getNumber(), dcDevices.size()); + } else { + // 下行 取最小的几个 + start.add(markArray[0]); + start.add(markArray[1]); + end.add("208"); + end.add("153.4"); + parameter.put("startStakeMark", start); + parameter.put("endStakeMark", end); + dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + dcDevices = dcDevices.subList(0, dcExecuteAction.getNumber()); + } + +// // 定义Comparator来比较DcDevice对象的stakeMark字段 +// Comparator comparator = Comparator.comparing(DcDevice::getStakeMark); +// // 对dcDevices进行升序排序 +// Collections.sort(dcDevices, comparator); +// // 对dcDevices进行降序排序 +// Collections.sort(dcDevices, comparator.reversed()); + } else if (searchRule.equals(3)) { + // 事件下游最近 + if (direction.equals("1")) { + // 上行 取最大的几个 + start.add(markArray[0]); + start.add(markArray[1]); + end.add("208"); + end.add("153.4"); + parameter.put("startStakeMark", start); + parameter.put("endStakeMark", end); + dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + dcDevices = dcDevices.subList(0, dcExecuteAction.getNumber()); + + } else { + // 下行 取最小的几个 + start.add("55"); + start.add("378.7"); + end.add(markArray[0]); + end.add(markArray[1]); + parameter.put("startStakeMark", start); + parameter.put("endStakeMark", end); + dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + dcDevices = dcDevices.subList(dcDevices.size() - dcExecuteAction.getNumber(), dcDevices.size()); + } + } else { + // 最近公里数 + Integer kilometers = Integer.parseInt(markArray[0].replaceAll("K", "")); + // 根据事件桩号、公里数 计算出 桩号范围 + start.add(String.valueOf(kilometers - dcExecuteAction.getNumber())); + start.add(markArray[1]); + end.add(String.valueOf(kilometers + dcExecuteAction.getNumber())); + end.add(markArray[1]); + // 构造查询条件 + parameter.put("startStakeMark", start); + parameter.put("endStakeMark", end); + parameter.put("deviceType", dcExecuteAction.getDeviceType()); + // 根据桩号范围,查询附近设备 + dcDevices = dcDeviceService.devicePileNumberQueryDevice(parameter); + } + + String deviceId = dcDevices.stream() + .map(DcDevice::getId) + .map(String::valueOf) + .collect(Collectors.joining(",")); + // 存储设备id 到 deviceIds 中 + deviceIds.append(","); + deviceIds.append(deviceId); + + try { + // 根据不通设备类型,执行不通的功能操作 + invokedFunction( + dcDevices, + JSON.parseObject(dcExecuteAction.getOtherConfig()), + resultArray); + } catch (Exception e) { + e.printStackTrace(); + } + + }); + // 创建一个 预案事件关联对象 + EventPlanAssoc eventPlanAssoc = new EventPlanAssoc(); + // 事件编号 + eventPlanAssoc.setEventId(dcEvent.getId()); + + // 区分是执行操作 还是 恢复操作 + if (dcEventAnDcEmergencyPlans.getOperationType().equals(1)) { + // 事件预案编号 + eventPlanAssoc.setEmergencyPlansId(dcEmergencyPlans.getId()); + eventPlanAssoc.setExecutingControlDevice(deviceIds.toString().replaceFirst(",", "")); + eventPlanAssoc.setExecutingControlResult(resultArray.toJSONString()); + eventPlanAssoc.setCreateTime(DateUtils.getNowDate()); + return eventPlanAssocMapper.insertEventPlanAssoc(eventPlanAssoc); + } else { + EventPlanAssoc selectEventPlanAssoc = eventPlanAssocMapper.selectByEventId(eventPlanAssoc); + selectEventPlanAssoc.setUpdateTime(DateUtils.getNowDate()); + selectEventPlanAssoc.setRecoveredControlDevice(deviceIds.toString().replaceFirst(",", "")); + selectEventPlanAssoc.setRecoveredControlResult(resultArray.toJSONString()); + return eventPlanAssocMapper.updateEventPlanAssoc(selectEventPlanAssoc); + } + + } + + /** + * 根据不通设备类型,执行不通的功能操作 + */ + public void invokedFunction(List dcDevices, JSONObject otherConfig, JSONArray resultArray) throws HttpException, IOException { + String iotDeviceId = ""; + String functionId = ""; + HashMap props = new HashMap<>(); + + for (DcDevice device : dcDevices) { + iotDeviceId = device.getIotDeviceId(); + + if (device.getDeviceType().equals(DeviceTypeConstants.DRIVING_GUIDANCE)) { + // 行车诱导 + functionId = DeviceFunctionIdConstants.DRIVING_GUIDANCE; + // 控制模式 1-手动 2-自动 3-万年历 + String controlModel = otherConfig.get("controlModel").toString(); + props.put("onWorkStatus", otherConfig.get("state").toString()); + props.put("inWorkStatus", otherConfig.get("state").toString()); + if (controlModel.equals("1")) { + props.put("mode", "00"); + } else if (controlModel.equals("2")) { + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String format = dateFormat.format(date); + String[] times = otherConfig.get("time").toString().split("-"); + props.put("mode", "01"); + props.put("startDisplayTime", format + " " + times[0]); + props.put("endDisplayTime", format + " " + times[1]); + } else { + props.put("mode", "02"); + } + + } else if (device.getDeviceType().equals(DeviceTypeConstants.VARIABLE_INFORMATION_FLAG)) { + // 可变信息标志 + functionId = DeviceFunctionIdConstants.VARIABLE_INFORMATION_FLAG; + } else { + break; + } + + AjaxResult ajaxResult = dcDeviceController.invokedFunction(iotDeviceId, functionId, props); + // 将调用结果存入到 resultArray(操作结果) 中 + JSONObject result = new JSONObject(); + result.put("device", device.getId()); + result.put("result", ajaxResult); + resultArray.add(result); + } + } + + /** * 新增事件预案 * diff --git a/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml b/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml new file mode 100644 index 00000000..82941ea3 --- /dev/null +++ b/zc-business/src/main/resources/mapper/business/EventPlanAssocMapper.xml @@ -0,0 +1,64 @@ + + + + + + insert into event_plan_assoc + + event_id, + emergency_plans_id, + executing_control_device, + recovered_control_device, + create_time, + update_time, + executing_control_result, + recovered_control_result, + + + #{eventId}, + #{emergencyPlansId}, + #{executingControlDevice}, + #{recoveredControlDevice}, + #{createTime}, + #{updateTime}, + #{executingControlResult}, + #{recoveredControlResult} + + + + + select id,event_id,emergency_plans_id,executing_control_device,recovered_control_device,create_time,update_time, + executing_control_result,recovered_control_result + from event_plan_assoc + + + + + + update event_plan_assoc + + event_id = #{eventId}, + emergency_plans_id = #{emergencyPlansId}, + + executing_control_device = #{executingControlDevice}, + + + recovered_control_device = #{recoveredControlDevice}, + + update_time = #{updateTime}, + + executing_control_result = #{executingControlResult}, + + + recovered_control_result = #{recoveredControlResult}, + + + where id = #{id} + + +