From ea8b0b473deecba49980fbc004deadefba77c00b Mon Sep 17 00:00:00 2001 From: songwenxuan <1924103812@qq.com> Date: Sun, 21 Sep 2025 12:20:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E7=89=A9=E8=81=94=E7=BD=91?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=95=B0=E6=8D=AE=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppPosiDeviceController.java | 249 ++++++++++++++++++ src/main/java/com/zcloud/util/R.java | 59 +++++ 2 files changed, 308 insertions(+) create mode 100644 src/main/java/com/zcloud/controller/AppPosiDeviceController.java create mode 100644 src/main/java/com/zcloud/util/R.java diff --git a/src/main/java/com/zcloud/controller/AppPosiDeviceController.java b/src/main/java/com/zcloud/controller/AppPosiDeviceController.java new file mode 100644 index 0000000..5ca226c --- /dev/null +++ b/src/main/java/com/zcloud/controller/AppPosiDeviceController.java @@ -0,0 +1,249 @@ +package com.zcloud.controller; + +import com.xxl.job.core.context.XxlJobHelper; +import com.zcloud.entity.PageData; +import com.zcloud.mapper.datasource.tbIron.TbIronPlcMapper; +import com.zcloud.mapper.dsno2.target.MesDeviceMonitoringMapper; +import com.zcloud.util.DateUtil; +import com.zcloud.util.R; +import com.zcloud.util.Tools; +import com.zcloud.util.UuidUtil; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.tools.Tool; +import java.util.*; +import java.util.stream.Collectors; + + +@RestController +@RequestMapping("app") +public class AppPosiDeviceController { + @Resource + private TbIronPlcMapper tbIronPlcMapper; + + @Resource + private MesDeviceMonitoringMapper mesDeviceMonitoringMapper; + + @PostMapping("/test1") + public R test1(@RequestBody HashMap parma) throws Exception { + System.out.println("———————————————————————————————————————————————————————————————————————————————————————————————————————————"); + // 1. 初始化分组Map,确保键唯一(使用LinkedHashMap保持插入顺序,可选) + Map>> groupMap = new LinkedHashMap<>(); + + for (Map.Entry entry : parma.entrySet()) { + String key = entry.getKey(); + // 提取前缀(统一处理为trimmed字符串,避免隐式空格导致的重复) + String[] keyParts = splitKeyIntoPrefixAndNumber(key); + String prefix = keyParts[0].trim(); // 去除可能的空格,确保键唯一 + + // 强制使用唯一键:若已存在该前缀,直接添加到现有列表;否则创建新列表 + groupMap.computeIfAbsent(prefix, k -> new ArrayList<>()).add(entry); + } + + // 2. 组内按数字排序(空数字视为0) + for (List> group : groupMap.values()) { + group.sort((e1, e2) -> { + String[] parts1 = splitKeyIntoPrefixAndNumber(e1.getKey()); + String[] parts2 = splitKeyIntoPrefixAndNumber(e2.getKey()); + int num1 = parseNumber(parts1[1]); + int num2 = parseNumber(parts2[1]); + return Integer.compare(num1, num2); + }); + } + + // 3. 打印分组(每个组只输出一次) + System.out.println("===== 传感器设备数据(去重分组输出) ====="); + + // 遍历分组Map(已去重,每个组只输出一次) + groupMap.forEach((prefix, sortedGroup) -> { + StringBuilder groupContent = new StringBuilder(); + for (Map.Entry entry : sortedGroup) { + groupContent.append(entry.getKey()).append(": ").append(entry.getValue()).append(","); + } + // 移除末尾多余的逗号 + if (groupContent.length() > 0) { + groupContent.setLength(groupContent.length() - 1); + } + // 输出分组 + System.out.println("【" + prefix + "组】:" + groupContent); + }); + System.out.println("———————————————————————————————————————————————————————————————————————————————————————————————————————————"); + return R.ok(); + } + + /** + * 解析数字部分(空或非数字均视为0) + */ + private int parseNumber(String numberPart) { + if (numberPart == null || numberPart.trim().isEmpty()) { + return 0; + } + try { + return Integer.parseInt(numberPart.trim()); + } catch (NumberFormatException e) { + return 0; + } + } + + /** + * 拆分键为前缀和数字部分(扩展匹配 z2zt、t2td、T2td、td,确保不同前缀正确分组) + */ + private String[] splitKeyIntoPrefixAndNumber(String key) { + if (key == null) { + return new String[]{"", null}; + } + String trimmedKey = key.trim(); // 去除首尾空格,避免干扰 + + // 优先匹配 T2zt 前缀 + if (trimmedKey.startsWith("T2zt")) { + String numberPart = trimmedKey.substring(4); // 截取 z2zt 后的内容作为数字部分 + return new String[]{"T2zt", numberPart}; + } + + // 匹配 t2zt 前缀 + if (trimmedKey.startsWith("t2zt")) { + String numberPart = trimmedKey.substring(4); // 截取 z2zt 后的内容作为数字部分 + return new String[]{"t2zt", numberPart}; + } + // 匹配 t2td 前缀 + else if (trimmedKey.startsWith("t2td")) { + String numberPart = trimmedKey.substring(4); // 截取 t2td 后的内容作为数字部分 + return new String[]{"t2td", numberPart}; + } + // 匹配 T2td 前缀(原逻辑保留) + else if (trimmedKey.startsWith("T2td")) { + String numberPart = trimmedKey.substring(4); // 截取 T2td 后的内容作为数字部分 + return new String[]{"T2td", numberPart}; + } + // 匹配 td 前缀(原逻辑保留) + else if (trimmedKey.startsWith("td")) { + String numberPart = trimmedKey.substring(2); // 截取 td 后的内容作为数字部分 + return new String[]{"td", numberPart}; + } + // 其他键:前缀为自身,无数字部分 + else { + return new String[]{trimmedKey, null}; + } + } + + @PostMapping("/receiver") + public R receiver(@RequestBody HashMap parma) throws Exception { + System.out.println("parma数据:" +parma); + // 定义处理批次数据 ID + String processingBatchId = UuidUtil.get32UUID(); + // 批处理时间 + String processingTime = DateUtil.date2Str(new Date()); + // td1 和 t2td1 的值是一氧化碳浓度 每次数据至多两条(安装在一起的设备) + String location = parma.get("location"); + // 根据设备的地点和td1或者是t2td1判断出设备对应系统中的哪个 + // 查出所有一氧化碳设备的阈值配置 + PageData equPd = new PageData(); + List targetAllList = tbIronPlcMapper.listTargetByEquId(equPd); + // 定义一个存储集合用于存储要入库的数据 + List> dataList = new ArrayList<>(); + if (location.equals("1#高炉中控室")) { + // 如果是1#高炉中控室,td1的值为1#高炉中控室(上)的CO浓度,t2td1的值为1#高炉中控室(下)的CO浓度。 + if (parma.containsKey("td1")) { + // 如果包含td1,证明1#高炉中控室(上)的CO浓度有值 将一氧化碳的浓度值、所属设备编码(EQUIPMENT_ID)、预警阈值传入方法 + dataList.add(saveData(parma.get("td1"), "8eab7aff5585192b028e9592e2a6c6e9", targetAllList, processingBatchId, processingTime)); + } else if (parma.containsKey("t2td1")) { + dataList.add(saveData(parma.get("t2td1"), "cf0c414e21e0413aac3ac53e53c33058", targetAllList, processingBatchId, processingTime)); + } + } else if (location.equals("2#高炉控制室")) { + System.out.println("2#高炉控制室"); + } else if (location.equals("3#高炉控制室")) { + System.out.println("3#高炉控制室"); + } else if (location.equals("型钢加热炉")) { + System.out.println("型钢加热炉"); + } else if (location.equals("15万高炉煤气柜")) { + System.out.println("15万高炉煤气柜"); + } + // 存储集合中处理好的数据 + mesDeviceMonitoringMapper.saveBatchFromMes(dataList); + XxlJobHelper.log("成功保存{}条物联网模块数据到本地数据库", dataList.size()); + return R.ok(); + } + + // 定义一个通用的保存数据的方法 + HashMap saveData(String CURRENT_VALUE, String EQUIPMENT_ID, List targetAllList, String processingBatchId, String processingTime) { + // 根据给出的设备ID,找出对应设备的预警阈值数据 + List collect = targetAllList.stream().filter(item -> !Tools.isEmpty(item.get("EQUIPMENT_ID")) && item.get("EQUIPMENT_ID").equals(EQUIPMENT_ID)).collect(Collectors.toList()); + // 定义数据Map + HashMap data = new HashMap<>(); + data.put("MONITORING_ID", UuidUtil.get32UUID()); + data.put("CURRENT_VALUE", CURRENT_VALUE); + data.put("PROCESSING_TIME", processingBatchId); + data.put("PROCESSING_BATCH_ID", processingTime); + data.put("INSERT_TIME", DateUtil.date2Str(new Date())); + data.put("WARNING", 0); // 是否告警 要完善相关告警逻辑进行判断 + data.put("GATHER_TIME", 5); + data.put("PLC_NAME", ""); + data.put("OVERVIEW_OF_ALERTS", ""); + // 每个设备只有一个监测数据阈值,也就是一氧化碳浓度 + if (collect.size() > 0) { + PageData pageData = collect.get(0); + data.put("TARGET_NAME", pageData.getString("TARGET_NAME")); + data.put("IPCDEVICE_ID", pageData.getString("IPCDEVICE_ID")); + data.put("PLC_ID", pageData.getString("PLC_ID")); + data.put("TARGET_TYPE", pageData.getString("TARGET_TYPE")); + data.put("TARGET_PLACE", pageData.getString("TARGET_PLACE")); + data.put("TARGET_UNIT", pageData.getString("TARGET_UNIT")); + data.put("THRESHOLD_UP_LIMIT", pageData.getString("THRESHOLD_UP_LIMIT")); + data.put("THRESHOLD_UP_UP_LIMIT", pageData.getString("THRESHOLD_UP_UP_LIMIT")); + data.put("THRESHOLD_DOWN_LIMIT", pageData.getString("THRESHOLD_DOWN_LIMIT")); + data.put("THRESHOLD_DOWN_DOWN_LIMIT", pageData.getString("THRESHOLD_DOWN_DOWN_LIMIT")); + data.put("RANGE_UP", pageData.getString("RANGE_UP")); + data.put("RANGE_DOWN", pageData.getString("RANGE_DOWN")); + data.put("TARGET_DESCRIPTION", pageData.getString("TARGET_DESCRIPTION")); + data.put("BIT_NO", pageData.getString("BIT_NO")); + data.put("SIGNAL_TYPE", pageData.getString("SIGNAL_TYPE")); + data.put("ALARM_VALUE", pageData.getString("ALARM_VALUE")); + data.put("TARGET_STATUS", pageData.getString("TARGET_STATUS")); + data.put("CORPINFO_ID", pageData.getString("CORPINFO_ID")); + } else { + data.put("IPCDEVICE_ID", ""); + data.put("PLC_ID", ""); + data.put("TARGET_TYPE", ""); + data.put("TARGET_PLACE", ""); + data.put("TARGET_UNIT", ""); + data.put("THRESHOLD_UP_LIMIT", ""); + data.put("THRESHOLD_UP_UP_LIMIT", ""); + data.put("THRESHOLD_DOWN_LIMIT", ""); + data.put("THRESHOLD_DOWN_DOWN_LIMIT", ""); + data.put("RANGE_UP", ""); + data.put("RANGE_DOWN", ""); + data.put("TARGET_DESCRIPTION", ""); + data.put("BIT_NO", ""); + data.put("SIGNAL_TYPE", ""); + data.put("ALARM_VALUE", ""); + data.put("TARGET_STATUS", ""); + data.put("CORPINFO_ID", ""); + } + return data; + } + // 参数示例 +// { +// "td1": "node0101", -》设备的CO浓度 +// "workshop": "高炉区域", -》车间 +// "equipment": "气体检测报警控制器", -》设备名称 +// "mode!": "ZD-Y32", -》 +// "vendor": "南京智达", -》设备厂家 +// "location": "1#高炉中控室", -》安装地点 +// "display area": "1#高炉中控室", -》安装地点 +// "host id": "T001", -》 + +// "t2td1": "node0201", -》设备的CO浓度 +// "t2zt1": "node0209", -》设备的状态 (不用管) +// "workshop": "高炉区域", -》车间 +// "equipment": "CO报警仪", -》设备名称 +// "mode!": "CL-9100", -》 +// "vendor": "深圳市科陆", -》设备厂家 +// "location": "1#高炉中控室", -》安装地点 +// "display area": "1#高炉中控室", -》安装地点 +// "host id": "T001-T002" -》 +// } +} diff --git a/src/main/java/com/zcloud/util/R.java b/src/main/java/com/zcloud/util/R.java new file mode 100644 index 0000000..9b855be --- /dev/null +++ b/src/main/java/com/zcloud/util/R.java @@ -0,0 +1,59 @@ + + +package com.zcloud.util; + +import org.apache.http.HttpStatus; + +import java.util.HashMap; +import java.util.Map; + +/** + * 返回数据 + * + * + */ +public class R extends HashMap { + private static final long serialVersionUID = 1L; + + public R() { + put("code", 200); + put("result", "success"); + } + + public static R error() { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员"); + } + + public static R error(String msg) { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); + } + + public static R error(int code, String msg) { + R r = new R(); + r.put("code", code); + r.put("result", "failed"); + r.put("msg", msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put("msg", msg); + return r; + } + + public static R ok(Map map) { + R r = new R(); + r.putAll(map); + return r; + } + + public static R ok() { + return new R(); + } + + public R put(String key, Object value) { + super.put(key, value); + return this; + } +}