fix: 塘口控制器列表,只有开关关联,无溶解氧探头时,显示问题,bug修复。

This commit is contained in:
tianyongbao
2026-03-27 21:30:23 +08:00
parent 7eb07611a6
commit d3312db206
2 changed files with 123 additions and 118 deletions

View File

@@ -212,7 +212,7 @@ public class PondController extends BaseController {
result.setPondName(pond.getPondName()); result.setPondName(pond.getPondName());
result.setKeepNightOpen(pond.getKeepNightOpen()); result.setKeepNightOpen(pond.getKeepNightOpen());
// 2. 查询塘口下的所有设备 // 2. 查询塘口下的所有设备device.pondId == pondId用于检测仪和挂了塘口的控制器
List<Device> devices = deviceMapper.selectList( List<Device> devices = deviceMapper.selectList(
new LambdaQueryWrapper<Device>() new LambdaQueryWrapper<Device>()
.eq(Device::getPondId, pondId) .eq(Device::getPondId, pondId)
@@ -220,18 +220,41 @@ public class PondController extends BaseController {
.orderByDesc(Device::getCreateTime) .orderByDesc(Device::getCreateTime)
); );
// 3. 查询塘口下的所有开关switch.pondId == pondId包含开关未挂塘口的控制器也能被找到
List<DeviceSwitch> allSwitches = deviceSwitchMapper.selectList(
new LambdaQueryWrapper<DeviceSwitch>()
.eq(DeviceSwitch::getPondId, pondId)
.orderByAsc(DeviceSwitch::getIndex)
);
// 4. 从开关中收集所有 deviceId补全那些本体未挂塘口的控制器
Set<Long> switchDeviceIds = allSwitches.stream()
.map(DeviceSwitch::getDeviceId)
.collect(Collectors.toSet());
// 5. 查询开关关联的控制器设备(排除已经在 devices 中的)
Set<Long> existDeviceIds = devices.stream().map(Device::getId).collect(Collectors.toSet());
List<Long> extraDeviceIds = switchDeviceIds.stream()
.filter(id -> !existDeviceIds.contains(id))
.collect(Collectors.toList());
if (!extraDeviceIds.isEmpty()) {
List<Device> extraDevices = deviceMapper.selectBatchIds(extraDeviceIds);
devices = new ArrayList<>(devices);
devices.addAll(extraDevices);
}
if (devices == null || devices.isEmpty()) { if (devices == null || devices.isEmpty()) {
result.setListDetector(List.of()); result.setListDetector(List.of());
result.setListController(List.of()); result.setListController(List.of());
return R.ok(result); return R.ok(result);
} }
// 3. 收集所有设备ID,用于查询联动控制和故障码 // 6. 收集所有设备ID
List<Long> deviceIds = devices.stream() List<Long> deviceIds = devices.stream()
.map(Device::getId) .map(Device::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 4. 批量查询所有设备的联动控制 // 7. 批量查询所有设备的联动控制
List<LinkedCtrl> allLinkedCtrls = linkedCtrlMapper.selectList( List<LinkedCtrl> allLinkedCtrls = linkedCtrlMapper.selectList(
new LambdaQueryWrapper<LinkedCtrl>() new LambdaQueryWrapper<LinkedCtrl>()
.in(LinkedCtrl::getDeviceId, deviceIds) .in(LinkedCtrl::getDeviceId, deviceIds)
@@ -239,14 +262,7 @@ public class PondController extends BaseController {
java.util.Map<Long, List<LinkedCtrl>> linkedCtrlsByDevice = allLinkedCtrls.stream() java.util.Map<Long, List<LinkedCtrl>> linkedCtrlsByDevice = allLinkedCtrls.stream()
.collect(Collectors.groupingBy(LinkedCtrl::getDeviceId)); .collect(Collectors.groupingBy(LinkedCtrl::getDeviceId));
// 5. 批量查询塘口的所有开关 // 8. 收集开关ID查询定时控制
List<DeviceSwitch> allSwitches = deviceSwitchMapper.selectList(
new LambdaQueryWrapper<DeviceSwitch>()
.eq(DeviceSwitch::getPondId, pondId)
.orderByAsc(DeviceSwitch::getIndex)
);
// 6. 收集开关ID,查询定时控制
List<Long> switchIds = allSwitches.stream() List<Long> switchIds = allSwitches.stream()
.map(DeviceSwitch::getId) .map(DeviceSwitch::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -260,20 +276,21 @@ public class PondController extends BaseController {
.collect(Collectors.groupingBy(TimingCtrl::getSwitchId)); .collect(Collectors.groupingBy(TimingCtrl::getSwitchId));
} }
// 7. 按设备ID分组开关 // 9. 按设备ID分组开关
java.util.Map<Long, List<DeviceSwitch>> switchesByDevice = allSwitches.stream() java.util.Map<Long, List<DeviceSwitch>> switchesByDevice = allSwitches.stream()
.collect(Collectors.groupingBy(DeviceSwitch::getDeviceId)); .collect(Collectors.groupingBy(DeviceSwitch::getDeviceId));
// 8. 批量查询故障码 // 10. 批量查询故障码(合并 devices + 开关关联设备 的所有 deviceId
Set<Long> controllerIds = devices.stream() Set<Long> allControllerIds = devices.stream()
.filter(d -> d.getDeviceType() != null && d.getDeviceType() == 2) .filter(d -> d.getDeviceType() != null && d.getDeviceType() == 2)
.map(Device::getId) .map(Device::getId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
allControllerIds.addAll(switchDeviceIds);
List<DeviceErrorCode> errorCodes = new ArrayList<>(); List<DeviceErrorCode> errorCodes = new ArrayList<>();
if (!controllerIds.isEmpty()) { if (!allControllerIds.isEmpty()) {
errorCodes = deviceErrorCodeMapper.selectList( errorCodes = deviceErrorCodeMapper.selectList(
new LambdaQueryWrapper<DeviceErrorCode>() new LambdaQueryWrapper<DeviceErrorCode>()
.in(DeviceErrorCode::getDeviceId, controllerIds) .in(DeviceErrorCode::getDeviceId, allControllerIds)
); );
} }
@@ -316,13 +333,27 @@ public class PondController extends BaseController {
} }
} }
// 10. 处理控制器列表 (仅测控一体机 deviceType=2) // 12. 处理控制器列表(与 C# 一致:以 allSwitches 为主线聚合,确保只挂开关到塘口的控制器也能被找到)
// 构建设备ID -> Device 的映射,便于下面按 deviceId 查询
java.util.Map<Long, Device> deviceById = devices.stream()
.collect(Collectors.toMap(Device::getId, d -> d, (a, b) -> a));
List<DeviceWithSwitchVo> controllerList = new ArrayList<>(); List<DeviceWithSwitchVo> controllerList = new ArrayList<>();
for (Device device : devices) { // 用 LinkedHashMap 保证控制器顺序,以 deviceId 为 key
if (device.getDeviceType() != null && device.getDeviceType() == 2) { java.util.LinkedHashMap<Long, DeviceWithSwitchVo> controllerMap = new java.util.LinkedHashMap<>();
// 转换为DeviceVo再复制到DeviceWithSwitchVo
for (DeviceSwitch sw : allSwitches) {
Long deviceId = sw.getDeviceId();
Device device = deviceById.get(deviceId);
if (device == null) {
continue; // 异常情况跳过
}
// 如果该控制器还没有创建,则创建并加入 map
DeviceWithSwitchVo deviceVo = controllerMap.get(deviceId);
if (deviceVo == null) {
DeviceVo baseDeviceVo = MapstructUtils.convert(device, DeviceVo.class); DeviceVo baseDeviceVo = MapstructUtils.convert(device, DeviceVo.class);
DeviceWithSwitchVo deviceVo = new DeviceWithSwitchVo(); deviceVo = new DeviceWithSwitchVo();
BeanUtil.copyProperties(baseDeviceVo, deviceVo); BeanUtil.copyProperties(baseDeviceVo, deviceVo);
// 初始化告警码信息 // 初始化告警码信息
@@ -339,40 +370,28 @@ public class PondController extends BaseController {
// 处理设备级故障码 (switchIndex=0的故障) // 处理设备级故障码 (switchIndex=0的故障)
StringBuilder errorMessage = new StringBuilder(); StringBuilder errorMessage = new StringBuilder();
for (DeviceErrorCode errorCode : errorCodes) { for (DeviceErrorCode errorCode : errorCodes) {
if (!errorCode.getDeviceId().equals(device.getId())) { if (!errorCode.getDeviceId().equals(deviceId)) continue;
continue; if (errorCode.getSwitchIndex() == null || errorCode.getSwitchIndex() != 0) continue;
} if (errorCode.getErrorCode() == null || errorCode.getErrorCode() > DefineDeviceErrorCode.PowerOff) continue;
if (errorCode.getSwitchIndex() == null || errorCode.getSwitchIndex() != 0) {
continue;
}
if (errorCode.getErrorCode() == null || errorCode.getErrorCode() > DefineDeviceErrorCode.PowerOff) {
continue;
}
// 电压告警需要开关打开
boolean isVoltageError = errorCode.getErrorCode() >= DefineDeviceErrorCode.Three_PhaseA_OverVoltage boolean isVoltageError = errorCode.getErrorCode() >= DefineDeviceErrorCode.Three_PhaseA_OverVoltage
&& errorCode.getErrorCode() <= DefineDeviceErrorCode.Three_PhaseC_UnderVoltage; && errorCode.getErrorCode() <= DefineDeviceErrorCode.Three_PhaseC_UnderVoltage;
if (device.getVoltageWarnOpen() != null && device.getVoltageWarnOpen() == 1 && isVoltageError if (device.getVoltageWarnOpen() != null && device.getVoltageWarnOpen() == 1 && isVoltageError
|| !isVoltageError) { || !isVoltageError) {
String msg = DefineDeviceErrorCode.getErrorMessage(errorCode.getErrorCode()); String msg = DefineDeviceErrorCode.getErrorMessage(errorCode.getErrorCode());
if (msg != null && !msg.isEmpty()) { if (msg != null && !msg.isEmpty() && !errorMessage.toString().contains(msg)) {
if (errorMessage.length() > 0 && !errorMessage.toString().contains(msg)) { if (errorMessage.length() > 0) errorMessage.append("");
errorMessage.append("");
}
if (!errorMessage.toString().contains(msg)) {
errorMessage.append(msg); errorMessage.append(msg);
} }
} }
} }
}
deviceVo.setErrorMessage(errorMessage.toString()); deviceVo.setErrorMessage(errorMessage.toString());
deviceVo.setListSwitch(new ArrayList<>());
controllerMap.put(deviceId, deviceVo);
}
// 查询该设备的开关列表 // 处理开关 Vo
List<DeviceSwitch> switches = switchesByDevice.getOrDefault(device.getId(), new ArrayList<>());
List<DeviceSwitchVo> switchVoList = new ArrayList<>();
for (DeviceSwitch sw : switches) {
DeviceSwitchVo switchVo = MapstructUtils.convert(sw, DeviceSwitchVo.class); DeviceSwitchVo switchVo = MapstructUtils.convert(sw, DeviceSwitchVo.class);
// 判断是否有联动控制 // 判断是否有联动控制
@@ -389,7 +408,7 @@ public class PondController extends BaseController {
// 判断是否有定时控制 // 判断是否有定时控制
switchVo.setIsTimingCtrl(false); switchVo.setIsTimingCtrl(false);
List<TimingCtrl> timingCtrls = timingCtrlsBySwitch.get(sw.getId()); List<TimingCtrl> timingCtrls = timingCtrlsBySwitch.get(sw.getId());
if (timingCtrls != null && !timingCtrls.isEmpty()) { if (timingCtrls != null) {
for (TimingCtrl timingCtrl : timingCtrls) { for (TimingCtrl timingCtrl : timingCtrls) {
if (timingCtrl.getIsOpen() != null && timingCtrl.getIsOpen() == 1) { if (timingCtrl.getIsOpen() != null && timingCtrl.getIsOpen() == 1) {
switchVo.setIsTimingCtrl(true); switchVo.setIsTimingCtrl(true);
@@ -400,18 +419,12 @@ public class PondController extends BaseController {
// 处理开关的故障码 // 处理开关的故障码
switchVo.setHasErrorCode(false); switchVo.setHasErrorCode(false);
StringBuilder devErrMsg = new StringBuilder(deviceVo.getErrorMessage() != null ? deviceVo.getErrorMessage() : "");
for (DeviceErrorCode errorCode : errorCodes) { for (DeviceErrorCode errorCode : errorCodes) {
if (!errorCode.getDeviceId().equals(sw.getDeviceId())) { if (!errorCode.getDeviceId().equals(deviceId)) continue;
continue; if (errorCode.getSwitchIndex() == null || !errorCode.getSwitchIndex().equals(sw.getIndex())) continue;
} if (errorCode.getErrorCode() == null || errorCode.getErrorCode() > DefineDeviceErrorCode.PowerOff) continue;
if (errorCode.getSwitchIndex() == null || !errorCode.getSwitchIndex().equals(sw.getIndex())) {
continue;
}
if (errorCode.getErrorCode() == null || errorCode.getErrorCode() > DefineDeviceErrorCode.PowerOff) {
continue;
}
// 电流告警范围
boolean hasElectricError = (errorCode.getErrorCode() >= DefineDeviceErrorCode.Three_Switch1OverElectricA boolean hasElectricError = (errorCode.getErrorCode() >= DefineDeviceErrorCode.Three_Switch1OverElectricA
&& errorCode.getErrorCode() <= DefineDeviceErrorCode.Three_Switch4ElectricEmpty) && errorCode.getErrorCode() <= DefineDeviceErrorCode.Three_Switch4ElectricEmpty)
|| (errorCode.getErrorCode() >= DefineDeviceErrorCode.One_Switch1OverElectric || (errorCode.getErrorCode() >= DefineDeviceErrorCode.One_Switch1OverElectric
@@ -420,26 +433,17 @@ public class PondController extends BaseController {
if (sw.getElectricWarnOpen() != null && sw.getElectricWarnOpen() == 1 && hasElectricError) { if (sw.getElectricWarnOpen() != null && sw.getElectricWarnOpen() == 1 && hasElectricError) {
switchVo.setHasErrorCode(true); switchVo.setHasErrorCode(true);
String msg = DefineDeviceErrorCode.getErrorMessage(errorCode.getErrorCode()); String msg = DefineDeviceErrorCode.getErrorMessage(errorCode.getErrorCode());
if (msg != null && !msg.isEmpty()) { if (msg != null && !msg.isEmpty() && !devErrMsg.toString().contains(msg)) {
if (errorMessage.length() > 0 && !errorMessage.toString().contains(msg)) { if (devErrMsg.length() > 0) devErrMsg.append("");
errorMessage.append(""); devErrMsg.append(msg);
}
if (!errorMessage.toString().contains(msg)) {
errorMessage.append(msg);
} }
} }
} }
deviceVo.setErrorMessage(devErrMsg.toString());
deviceVo.getListSwitch().add(switchVo);
} }
switchVoList.add(switchVo); controllerList.addAll(controllerMap.values());
}
// 更新设备的错误信息(包含开关的错误)
deviceVo.setErrorMessage(errorMessage.toString());
deviceVo.setListSwitch(switchVoList);
controllerList.add(deviceVo);
}
}
result.setListDetector(detectorList); result.setListDetector(detectorList);
result.setListController(controllerList); result.setListController(controllerList);

View File

@@ -15,6 +15,7 @@ import com.intc.fishery.domain.DeviceCorrectRecord;
import com.intc.fishery.domain.DeviceBindRecord; import com.intc.fishery.domain.DeviceBindRecord;
import com.intc.fishery.domain.DeviceErrorCode; import com.intc.fishery.domain.DeviceErrorCode;
import com.intc.fishery.domain.AquUser; import com.intc.fishery.domain.AquUser;
import com.intc.fishery.constant.DefineDeviceWarnCode;
import com.intc.fishery.domain.bo.*; import com.intc.fishery.domain.bo.*;
import com.intc.fishery.domain.vo.DeviceSwitchVo; import com.intc.fishery.domain.vo.DeviceSwitchVo;
import com.intc.fishery.mapper.DeviceMapper; import com.intc.fishery.mapper.DeviceMapper;
@@ -969,12 +970,12 @@ public class IotController extends BaseController {
// 获取设备属性 // 获取设备属性
Map<String, Object> deviceProperties = iotDeviceService.queryDeviceProperties(iotId); Map<String, Object> deviceProperties = iotDeviceService.queryDeviceProperties(iotId);
// 初始化警告码:默认探头离线且未校准 (0x0081) // 初始化警告码:默认探头未校准 (OxyDetectorNoCorrect)
int warnCode = 0x0081; int warnCode = DefineDeviceWarnCode.OxyDetectorNoCorrect;
// 如果设备离线,添加设备离线警告 // 如果设备离线,添加设备离线警告
if (status != null && "OFFLINE".equalsIgnoreCase(status)) { if (status != null && "OFFLINE".equalsIgnoreCase(status)) {
warnCode |= 0x0080; // 设备离线 (0x0080) warnCode |= DefineDeviceWarnCode.DeviceOffline;
} }
// 计算设备数量,用于生成设备名称 // 计算设备数量,用于生成设备名称
@@ -997,7 +998,7 @@ public class IotController extends BaseController {
} else { } else {
// 检查是否已过期 // 检查是否已过期
if (device.getDeadTime() != null && now.after(device.getDeadTime())) { if (device.getDeadTime() != null && now.after(device.getDeadTime())) {
warnCode |= 0x0040; // 设备时间到期 (0x0040) warnCode |= DefineDeviceWarnCode.DeviceTimeDead;
} }
} }
@@ -1121,7 +1122,7 @@ public class IotController extends BaseController {
try { try {
int tcorrect = Integer.parseInt(value.toString()); int tcorrect = Integer.parseInt(value.toString());
if (tcorrect == 1) { if (tcorrect == 1) {
warnCode &= ~0x0001; // 清除未校准标记 warnCode &= ~DefineDeviceWarnCode.OxyDetectorNoCorrect; // 清除未校准标记
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
log.warn("无法解析校准状态: {}", value); log.warn("无法解析校准状态: {}", value);
@@ -1239,7 +1240,7 @@ public class IotController extends BaseController {
switchIndex = errorCode - 0x200B + 1; switchIndex = errorCode - 0x200B + 1;
// 断电告警 // 断电告警
} else if (errorCode == 0x3001) { } else if (errorCode == 0x3001) {
warnCode |= 0x0020; // ErrorPowerOff warnCode |= DefineDeviceWarnCode.ErrorPowerOff; // ErrorPowerOff
} }
} }
@@ -1479,7 +1480,7 @@ public class IotController extends BaseController {
try { try {
int tcorrect = Integer.parseInt(value.toString()); int tcorrect = Integer.parseInt(value.toString());
if (tcorrect == 1) { if (tcorrect == 1) {
warnCode &= ~0x0001; // 清除未校准标记 warnCode &= ~DefineDeviceWarnCode.OxyDetectorNoCorrect; // 清除未校准标记
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
log.warn("无法解析校准状态: {}", value); log.warn("无法解析校准状态: {}", value);
@@ -1612,8 +1613,8 @@ public class IotController extends BaseController {
// 更新设备警告码:清除未校准标记 // 更新设备警告码:清除未校准标记
int warnCode = device.getWarnCode() != null ? device.getWarnCode() : 0; int warnCode = device.getWarnCode() != null ? device.getWarnCode() : 0;
if ((warnCode & 0x0001) != 0) { if ((warnCode & DefineDeviceWarnCode.OxyDetectorNoCorrect) != 0) {
warnCode &= ~0x0001; // 清除未校准标记 warnCode &= ~DefineDeviceWarnCode.OxyDetectorNoCorrect; // 清除未校准标记
} }
// 更新设备 // 更新设备