fix: 微信小程序接口对接修改,联调测试问题修复。
This commit is contained in:
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.intc.common.json.handler.BigNumberSerializer;
|
||||
import com.intc.common.json.handler.CustomDateDeserializer;
|
||||
import com.intc.common.json.handler.LongDeserializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
@@ -33,8 +34,12 @@ public class JacksonConfig {
|
||||
public Module registerJavaTimeModule() {
|
||||
// 全局配置序列化返回 JSON 处理
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
// Long 类型序列化:超出JS安全范围转字符串
|
||||
javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
|
||||
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
|
||||
// Long 类型反序列化:支持字符串转 Long
|
||||
javaTimeModule.addDeserializer(Long.class, new LongDeserializer());
|
||||
javaTimeModule.addDeserializer(Long.TYPE, new LongDeserializer());
|
||||
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
|
||||
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.intc.common.json.handler;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Long类型反序列化器
|
||||
* 支持从字符串或数字解析Long,解决前端精度丢失问题
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
public class LongDeserializer extends JsonDeserializer<Long> {
|
||||
|
||||
@Override
|
||||
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
String value = p.getValueAsString();
|
||||
if (value == null || value.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid Long value: " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,11 @@ public class DefineDeviceWarnCode {
|
||||
*/
|
||||
public static final int DeviceDead = 64;
|
||||
|
||||
/**
|
||||
* 溶解氧探头未校准
|
||||
*/
|
||||
public static final int OxyDetectorNoCorrect = 1;
|
||||
|
||||
private DefineDeviceWarnCode() {
|
||||
}
|
||||
|
||||
|
||||
@@ -24,16 +24,36 @@ import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceSimpleVo;
|
||||
import com.intc.fishery.domain.vo.PublicPondIdNameVo;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceSwitchSimpleVo;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceBaseData;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceLinkedCtrl;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceDeadInfo;
|
||||
import com.intc.fishery.domain.bo.ReqId;
|
||||
import com.intc.fishery.domain.bo.ReqSetOxyTempWarnCall;
|
||||
import com.intc.fishery.domain.bo.ReqSetOxyWarnValue;
|
||||
import com.intc.fishery.domain.bo.ReqSetTempWarnValue;
|
||||
import com.intc.fishery.domain.bo.ReqDeviceCalibrate;
|
||||
import com.intc.fishery.domain.bo.ReqDeviceSalinityCompensation;
|
||||
import com.intc.fishery.domain.bo.ReqChangeName;
|
||||
import com.intc.fishery.domain.bo.ReqTurnOpen;
|
||||
import com.intc.fishery.domain.Device;
|
||||
import com.intc.fishery.domain.DeviceSwitch;
|
||||
import com.intc.fishery.domain.Pond;
|
||||
import com.intc.fishery.domain.LinkedCtrl;
|
||||
import com.intc.fishery.domain.DeviceCorrectRecord;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.mapper.DeviceSwitchMapper;
|
||||
import com.intc.fishery.mapper.PondMapper;
|
||||
import com.intc.fishery.mapper.LinkedCtrlMapper;
|
||||
import com.intc.fishery.mapper.DeviceCorrectRecordMapper;
|
||||
import com.intc.fishery.constant.DefineDeviceWarnCode;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.Date;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* 设备管理
|
||||
@@ -51,6 +71,8 @@ public class DeviceController extends BaseController {
|
||||
private final DeviceMapper deviceMapper;
|
||||
private final DeviceSwitchMapper deviceSwitchMapper;
|
||||
private final PondMapper pondMapper;
|
||||
private final LinkedCtrlMapper linkedCtrlMapper;
|
||||
private final DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
|
||||
/**
|
||||
* 查询设备管理列表
|
||||
@@ -77,7 +99,7 @@ public class DeviceController extends BaseController {
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("fishery:device:query")
|
||||
// @SaCheckPermission("fishery:device:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<DeviceVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
@@ -260,4 +282,698 @@ public class DeviceController extends BaseController {
|
||||
return R.ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个设备完整信息
|
||||
* 包含设备基础信息、塘口信息、开关列表(测控一体机)、联动控制列表
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID)
|
||||
* @return 设备完整信息
|
||||
*/
|
||||
@PostMapping("/one_device_info")
|
||||
public R<PublicDeviceBaseData> fetchOneDevice(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqId request) {
|
||||
|
||||
// 查询设备基础信息
|
||||
Device device = deviceMapper.selectById(request.getId());
|
||||
if (device == null) {
|
||||
return R.fail("设备不存在");
|
||||
}
|
||||
|
||||
// 构建返回对象
|
||||
PublicDeviceBaseData data = new PublicDeviceBaseData();
|
||||
data.setId(device.getId());
|
||||
data.setDeviceName(device.getDeviceName());
|
||||
data.setSerialNum(device.getSerialNum());
|
||||
data.setDeviceType(device.getDeviceType());
|
||||
data.setBindTime(device.getBindTime());
|
||||
data.setDeadTime(device.getDeadTime());
|
||||
data.setIsOxygenUsed(device.getIsOxygenUsed());
|
||||
data.setOxyWarnTelOpen(device.getOxyWarnCallOpen());
|
||||
data.setOxyWarnTelNoDis(device.getOxyWarnCallNoDis());
|
||||
data.setOxyWarnLower(device.getOxyWarnLower());
|
||||
data.setTempWarnTelOpen(device.getTempWarnCallOpen());
|
||||
data.setTempWarnTelNoDis(device.getTempWarnCallNoDis());
|
||||
data.setTempWarnUpper(device.getTempWarnUpper());
|
||||
data.setTempWarnLower(device.getTempWarnLower());
|
||||
data.setSalinityCompensation(device.getSalinityCompensation());
|
||||
data.setInputVoltage(device.getInputVoltage());
|
||||
data.setVoltageWarnOpen(device.getVoltageWarnOpen());
|
||||
|
||||
// 设置塘口信息
|
||||
if (device.getPondId() != null && device.getPondId() > 0) {
|
||||
Pond pond = pondMapper.selectById(device.getPondId());
|
||||
if (pond != null) {
|
||||
PublicPondIdNameVo pondInfo = new PublicPondIdNameVo();
|
||||
pondInfo.setId(pond.getId());
|
||||
pondInfo.setPondName(pond.getPondName());
|
||||
data.setPondInfo(pondInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是测控一体机(deviceType=2),查询开关列表
|
||||
if (device.getDeviceType() != null && device.getDeviceType() == 2) {
|
||||
List<DeviceSwitch> switches = deviceSwitchMapper.selectList(
|
||||
new LambdaQueryWrapper<DeviceSwitch>()
|
||||
.eq(DeviceSwitch::getDeviceId, device.getId())
|
||||
.orderByAsc(DeviceSwitch::getIndex)
|
||||
);
|
||||
|
||||
// 收集开关关联的塘口ID
|
||||
List<Long> switchPondIds = switches.stream()
|
||||
.map(DeviceSwitch::getPondId)
|
||||
.filter(id -> id != null && id > 0)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 批量查询塘口
|
||||
Map<Long, Pond> pondMap = Map.of();
|
||||
if (!switchPondIds.isEmpty()) {
|
||||
List<Pond> ponds = pondMapper.selectBatchIds(switchPondIds);
|
||||
pondMap = ponds.stream()
|
||||
.collect(Collectors.toMap(Pond::getId, Function.identity()));
|
||||
}
|
||||
|
||||
Map<Long, Pond> finalPondMap = pondMap;
|
||||
|
||||
List<PublicDeviceSwitchSimpleVo> switchVos = switches.stream()
|
||||
.map(s -> {
|
||||
PublicDeviceSwitchSimpleVo switchVo = new PublicDeviceSwitchSimpleVo();
|
||||
switchVo.setId(s.getId());
|
||||
switchVo.setIndex(s.getIndex());
|
||||
switchVo.setSwitchName(s.getSwitchName());
|
||||
|
||||
// 设置开关的塘口信息
|
||||
if (s.getPondId() != null && s.getPondId() > 0) {
|
||||
Pond pond = finalPondMap.get(s.getPondId());
|
||||
if (pond != null) {
|
||||
PublicPondIdNameVo pondInfo = new PublicPondIdNameVo();
|
||||
pondInfo.setId(pond.getId());
|
||||
pondInfo.setPondName(pond.getPondName());
|
||||
switchVo.setPondInfo(pondInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return switchVo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
data.setListSwitch(switchVos);
|
||||
}
|
||||
|
||||
// 查询联动控制列表
|
||||
List<LinkedCtrl> linkedCtrls = linkedCtrlMapper.selectList(
|
||||
new LambdaQueryWrapper<LinkedCtrl>()
|
||||
.eq(LinkedCtrl::getDeviceId, device.getId())
|
||||
);
|
||||
|
||||
if (linkedCtrls != null && !linkedCtrls.isEmpty()) {
|
||||
// 收集所有联动控制ID
|
||||
List<Long> linkedCtrlIds = linkedCtrls.stream()
|
||||
.map(LinkedCtrl::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 查询关联的开关
|
||||
List<DeviceSwitch> linkedSwitches = deviceSwitchMapper.selectList(
|
||||
new LambdaQueryWrapper<DeviceSwitch>()
|
||||
.in(DeviceSwitch::getLinkedCtrlId, linkedCtrlIds)
|
||||
);
|
||||
|
||||
// 按联动控制ID分组开关
|
||||
Map<Long, List<DeviceSwitch>> switchesByLinkedCtrl = linkedSwitches.stream()
|
||||
.collect(Collectors.groupingBy(DeviceSwitch::getLinkedCtrlId));
|
||||
|
||||
// 构建联动控制VO列表
|
||||
List<PublicDeviceLinkedCtrl> linkedCtrlVos = linkedCtrls.stream()
|
||||
.map(lc -> {
|
||||
PublicDeviceLinkedCtrl vo = new PublicDeviceLinkedCtrl();
|
||||
vo.setId(lc.getId());
|
||||
vo.setDeviceId(lc.getDeviceId());
|
||||
vo.setOxyUpperOpen(lc.getOxyUpperOpen());
|
||||
vo.setOxyUpperValue(lc.getOxyUpperValue());
|
||||
vo.setOxyLowerOpen(lc.getOxyLowerOpen());
|
||||
vo.setOxyLowerValue(lc.getOxyLowerValue());
|
||||
|
||||
// 设置关联的开关列表
|
||||
List<DeviceSwitch> switches = switchesByLinkedCtrl.getOrDefault(lc.getId(), List.of());
|
||||
List<PublicDeviceSwitchSimpleVo> switchVos = switches.stream()
|
||||
.map(s -> {
|
||||
PublicDeviceSwitchSimpleVo switchVo = new PublicDeviceSwitchSimpleVo();
|
||||
switchVo.setId(s.getId());
|
||||
switchVo.setSwitchName(s.getSwitchName());
|
||||
return switchVo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
vo.setListSwitch(switchVos);
|
||||
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
data.setListLinkedCtr(linkedCtrlVos);
|
||||
} else {
|
||||
data.setListLinkedCtr(List.of());
|
||||
}
|
||||
|
||||
return R.ok(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置溶解氧/温度告警开关
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/set_oxy_warn_call")
|
||||
public R<Void> setOxyWarnCall(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqSetOxyTempWarnCall request) {
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getDeviceName,
|
||||
Device::getSerialNum, Device::getOxyWarnCallOpen,
|
||||
Device::getOxyWarnCallNoDis, Device::getTempWarnCallOpen,
|
||||
Device::getTempWarnCallNoDis)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// type=1: 溶解氧告警设置
|
||||
if (request.getType() == 1) {
|
||||
// 检查是否需要更新
|
||||
if (device.getOxyWarnCallOpen().equals(request.getIsOpen())
|
||||
&& device.getOxyWarnCallNoDis().equals(request.getIsNoDisturb())) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 更新溶解氧告警配置
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.set(Device::getOxyWarnCallOpen, request.getIsOpen())
|
||||
.set(Device::getOxyWarnCallNoDis, request.getIsNoDisturb())
|
||||
.set(Device::getOxyWarnCallLastTime, new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000))
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),溶解氧告警开关:%s, 免打扰开关:%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(),
|
||||
// request.getIsOpen() == 1 ? "打开" : "关闭",
|
||||
// request.getIsNoDisturb() == 1 ? "打开" : "关闭"));
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
// type=2: 温度告警设置
|
||||
else if (request.getType() == 2) {
|
||||
// 检查是否需要更新
|
||||
if (device.getTempWarnCallOpen().equals(request.getIsOpen())
|
||||
&& device.getTempWarnCallNoDis().equals(request.getIsNoDisturb())) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 更新温度告警配置
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.set(Device::getTempWarnCallOpen, request.getIsOpen())
|
||||
.set(Device::getTempWarnCallNoDis, request.getIsNoDisturb())
|
||||
.set(Device::getTempWarnCallLastTime, new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000))
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),温度告警开关:%s, 免打扰开关:%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(),
|
||||
// request.getIsOpen() == 1 ? "打开" : "关闭",
|
||||
// request.getIsNoDisturb() == 1 ? "打开" : "关闭"));
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
else {
|
||||
return R.fail("参数错误:类型必须为1或2");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置溶解氧告警值
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/set_oxy_warn_value")
|
||||
public R<Void> setOxyWarnValue(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqSetOxyWarnValue request) {
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.select(Device::getDeviceName, Device::getSerialNum, Device::getUserId,
|
||||
Device::getOxyWarnLower, Device::getDeadTime)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 保存旧值用于日志记录
|
||||
Double oldValue = device.getOxyWarnLower();
|
||||
|
||||
// 更新溶解氧下限告警值
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.set(Device::getOxyWarnLower, request.getOxyWarnLower())
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// 记录操作日志(仅当值发生变化时)
|
||||
if (oldValue == null || !oldValue.equals(request.getOxyWarnLower())) {
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),设置溶解氧下限告警值:%smg/L。",
|
||||
// device.getDeviceName(), device.getSerialNum(),
|
||||
// request.getOxyWarnLower()));
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置温度告警值
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/set_temp_warn_value")
|
||||
public R<Void> setTempWarnValue(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqSetTempWarnValue request) {
|
||||
|
||||
// 验证温度上下限
|
||||
if (request.getTempWarnUpper() <= request.getTempWarnLower()) {
|
||||
return R.fail("温度上限必须高于下限值");
|
||||
}
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.select(Device::getDeviceName, Device::getSerialNum, Device::getUserId,
|
||||
Device::getTempWarnUpper, Device::getTempWarnLower, Device::getDeadTime)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 保存旧值用于日志记录
|
||||
Double oldUpper = device.getTempWarnUpper();
|
||||
Double oldLower = device.getTempWarnLower();
|
||||
|
||||
// 更新温度告警值
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.set(Device::getTempWarnUpper, request.getTempWarnUpper())
|
||||
.set(Device::getTempWarnLower, request.getTempWarnLower())
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// 记录操作日志(仅当值发生变化时)
|
||||
if (oldUpper == null || Math.abs(oldUpper - request.getTempWarnUpper()) > 0.00001) {
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),设置温度上限告警值:%s℃。",
|
||||
// device.getDeviceName(), device.getSerialNum(),
|
||||
// request.getTempWarnUpper()));
|
||||
}
|
||||
if (oldLower == null || Math.abs(oldLower - request.getTempWarnLower()) > 0.00001) {
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),设置温度下限告警值:%s℃。",
|
||||
// device.getDeviceName(), device.getSerialNum(),
|
||||
// request.getTempWarnLower()));
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备饱和度
|
||||
*
|
||||
* @param request 请求对象(包含设备ID)
|
||||
* @return 饱和度值
|
||||
*/
|
||||
@PostMapping("/get_saturability")
|
||||
public R<Double> getSaturability(
|
||||
@Validated @RequestBody ReqId request) {
|
||||
|
||||
// 查询设备的饱和度值
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getValueSaturability)
|
||||
);
|
||||
|
||||
if (device == null) {
|
||||
return R.fail("设备不存在");
|
||||
}
|
||||
|
||||
// 返回饱和度值,如果为null则返回0.0
|
||||
Double saturability = device.getValueSaturability();
|
||||
return R.ok(saturability != null ? saturability : 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改设备名称
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID和新名称)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/update_name")
|
||||
public R<Void> changeDeviceName(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqChangeName request) {
|
||||
|
||||
// 查询设备的用户ID
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId)
|
||||
);
|
||||
|
||||
// 验证设备存在性和权限
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 更新设备名称
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getDeviceName, request.getNewName())
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询即将到期设备列表
|
||||
* 返回当前时间到未来1个月内将要到期的设备
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @return 即将到期的设备列表
|
||||
*/
|
||||
@GetMapping("/list_device_dead")
|
||||
public R<List<PublicDeviceDeadInfo>> queryListDeviceDead(
|
||||
@RequestParam("rootUserId") Long rootUserId) {
|
||||
|
||||
// 计算时间范围:当前时间到未来1个月
|
||||
Date now = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(now);
|
||||
calendar.add(Calendar.MONTH, 1);
|
||||
Date oneMonthLater = calendar.getTime();
|
||||
|
||||
// 查询即将到期的设备
|
||||
List<Device> devices = deviceMapper.selectList(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getUserId, rootUserId)
|
||||
.gt(Device::getDeadTime, now)
|
||||
.le(Device::getDeadTime, oneMonthLater)
|
||||
.ge(Device::getWarnCode, 0)
|
||||
.select(Device::getId, Device::getDeviceName, Device::getSerialNum, Device::getDeadTime)
|
||||
.orderByAsc(Device::getDeadTime)
|
||||
);
|
||||
|
||||
// 转换为VO列表
|
||||
List<PublicDeviceDeadInfo> list = devices.stream()
|
||||
.map(device -> {
|
||||
PublicDeviceDeadInfo vo = new PublicDeviceDeadInfo();
|
||||
vo.setId(device.getId());
|
||||
vo.setDeviceName(device.getDeviceName());
|
||||
vo.setSerialNum(device.getSerialNum());
|
||||
vo.setDeadTime(device.getDeadTime());
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备从塘口移除
|
||||
* 将设备从当前塘口中移除,同时删除关联的联动控制和告警信息
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/break_pond")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<Void> breakPond(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqId request) {
|
||||
|
||||
// 查询设备信息,包含塘口关联
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getDeviceName,
|
||||
Device::getSerialNum, Device::getDeviceType, Device::getPondId)
|
||||
);
|
||||
|
||||
// 验证设备存在性和权限
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 如果设备有关联的塘口,执行移除操作
|
||||
if (device.getPondId() != null && device.getPondId() > 0) {
|
||||
// 查询塘口名称用于日志记录
|
||||
Pond pond = pondMapper.selectOne(
|
||||
new LambdaQueryWrapper<Pond>()
|
||||
.eq(Pond::getId, device.getPondId())
|
||||
.select(Pond::getId, Pond::getPondName)
|
||||
);
|
||||
|
||||
String pondName = pond != null ? pond.getPondName() : "未知塘口";
|
||||
|
||||
// 删除设备关联的所有联动控制
|
||||
linkedCtrlMapper.delete(
|
||||
new LambdaQueryWrapper<LinkedCtrl>()
|
||||
.eq(LinkedCtrl::getDeviceId, device.getId())
|
||||
);
|
||||
|
||||
// 更新设备:移除塘口关联,清除告警状态
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getPondId, null)
|
||||
.set(Device::getIsTempWarnExist, 0)
|
||||
.set(Device::getIsOxygenWarnExist, 0)
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// TODO: 记录操作日志
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s) 从 %s 移除。",
|
||||
// device.getDeviceName(), device.getSerialNum(), pondName));
|
||||
|
||||
// TODO: 清除设备告警等待和通知
|
||||
// await EventHelper.RemoveDeviceWarnWaitAndNotice(request.getId(), DefineDeviceWarnCode.None);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置电压告警开关
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID和开关状态)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/voltage_check_open")
|
||||
public R<Void> updateDetectVoltageOpen(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqTurnOpen request) {
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getSerialNum,
|
||||
Device::getDeviceName, Device::getDeviceType,
|
||||
Device::getVoltageWarnOpen, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
// 验证设备存在性、权限和设备类型(必须是测控一体机)
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId) || device.getDeviceType() == null || device.getDeviceType() != 2) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 检查开关状态是否需要更新
|
||||
if (device.getVoltageWarnOpen() != null && device.getVoltageWarnOpen().equals(request.getIsOpen())) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 更新电压告警开关
|
||||
boolean updated = deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getVoltageWarnOpen, request.getIsOpen())
|
||||
) > 0;
|
||||
|
||||
if (!updated) {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// TODO: 记录操作日志
|
||||
String op = request.getIsOpen() == 1 ? "开启" : "关闭";
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s)设置电压告警开关:%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(), op));
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置测控一体机溶解氧启用/禁用
|
||||
* 启用时:同时启用溶解氧和温度告警及免打扰
|
||||
* 禁用时:关闭溶解氧并删除所有联动控制
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID和开关状态)
|
||||
* @return 设备完整信息
|
||||
*/
|
||||
@PutMapping("/set_controller_oxy_open")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<PublicDeviceBaseData> setControllerOxyOpen(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqTurnOpen request) {
|
||||
|
||||
// 查询设备基本信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getDeviceName, Device::getSerialNum)
|
||||
);
|
||||
|
||||
// 验证设备存在性和权限
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 根据开关状态执行不同逻辑
|
||||
if (request.getIsOpen() == 1) {
|
||||
// 启用溶解氧:同时启用相关告警和免打扰
|
||||
deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getIsOxygenUsed, 1)
|
||||
.set(Device::getOxyWarnCallOpen, 1)
|
||||
.set(Device::getOxyWarnCallNoDis, 1)
|
||||
.set(Device::getTempWarnCallOpen, 1)
|
||||
.set(Device::getTempWarnCallNoDis, 1)
|
||||
);
|
||||
} else {
|
||||
// 禁用溶解氧:关闭溶解氧并删除所有联动控制
|
||||
deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getIsOxygenUsed, 0)
|
||||
);
|
||||
|
||||
// 删除设备的所有联动控制
|
||||
linkedCtrlMapper.delete(
|
||||
new LambdaQueryWrapper<LinkedCtrl>()
|
||||
.eq(LinkedCtrl::getDeviceId, request.getId())
|
||||
);
|
||||
}
|
||||
|
||||
// 查询更新后的设备完整信息
|
||||
ReqId reqId = new ReqId();
|
||||
reqId.setId(request.getId());
|
||||
R<PublicDeviceBaseData> result = fetchOneDevice(rootUserId, reqId);
|
||||
|
||||
if (!R.isSuccess(result) || result.getData() == null) {
|
||||
return R.fail("查询设备信息失败");
|
||||
}
|
||||
|
||||
PublicDeviceBaseData deviceBaseData = result.getData();
|
||||
|
||||
// 验证设备类型必须是测控一体机
|
||||
if (deviceBaseData.getDeviceType() == null || deviceBaseData.getDeviceType() != 2) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 如果是禁用溶解氧,需要清除相关告警
|
||||
if (request.getIsOpen() == 0) {
|
||||
// TODO: 清除设备告警等待和通知
|
||||
// 清除探头离线相关告警:溶解氧探头、PH探头、盐度探头
|
||||
// await EventHelper.RemoveDeviceWarnWaitAndNotice(deviceBaseData.getId(),
|
||||
// DefineDeviceWarnCode.DetectorOxyOffline |
|
||||
// DefineDeviceWarnCode.DetectorPHOffline |
|
||||
// DefineDeviceWarnCode.DetectorSalinityOffline);
|
||||
}
|
||||
|
||||
// TODO: 记录操作日志
|
||||
String operation = request.getIsOpen() == 1 ? "启用溶解氧" : "禁用溶解氧";
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(), operation));
|
||||
|
||||
return R.ok(deviceBaseData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package com.intc.fishery.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.intc.fishery.domain.bo.ReqId;
|
||||
import com.intc.fishery.domain.bo.ReqChangeName;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSimpleDto;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSwitchBaseData;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
@@ -39,7 +43,7 @@ public class DeviceSwitchController extends BaseController {
|
||||
/**
|
||||
* 查询测控一体机开关列表
|
||||
*/
|
||||
@SaCheckPermission("fishery:deviceSwitch:list")
|
||||
// @SaCheckPermission("fishery:deviceSwitch:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<DeviceSwitchVo> list(DeviceSwitchBo bo, PageQuery pageQuery) {
|
||||
return deviceSwitchService.queryPageList(bo, pageQuery);
|
||||
@@ -102,4 +106,58 @@ public class DeviceSwitchController extends BaseController {
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(deviceSwitchService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据塘口ID查询塘口下的设备及其开关信息
|
||||
*
|
||||
* @param request 塘口ID请求对象
|
||||
* @return 设备及开关列表
|
||||
*/
|
||||
// @SaCheckPermission("fishery:deviceSwitch:query")
|
||||
@PostMapping("/get_pond_switch")
|
||||
public R<List<PublicDeviceSimpleDto>> getPondSwitch(@Validated @RequestBody ReqId request) {
|
||||
return R.ok(deviceSwitchService.getPondSwitch(request.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个开关的基础信息
|
||||
*
|
||||
* @param request 开关ID请求对象
|
||||
* @return 开关基础信息
|
||||
*/
|
||||
// @SaCheckPermission("fishery:deviceSwitch:query")
|
||||
@PostMapping("/one_switch_info")
|
||||
public R<PublicDeviceSwitchBaseData> getOneSwitchInfo(@Validated @RequestBody ReqId request) {
|
||||
return R.ok(deviceSwitchService.getOneSwitchInfo(request.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改开关名称
|
||||
*
|
||||
* @param request 修改名称请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
// @SaCheckPermission("fishery:deviceSwitch:edit")
|
||||
@Log(title = "修改开关名称", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/update_name")
|
||||
public R<Void> changeSwitchName(@Validated @RequestBody ReqChangeName request) {
|
||||
deviceSwitchService.changeSwitchName(request.getId(), request.getNewName());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置电流告警开关
|
||||
*
|
||||
* @param request 开关状态请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
// @SaCheckPermission("fishery:deviceSwitch:edit")
|
||||
@Log(title = "设置电流告警开关", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/electric_check_open")
|
||||
public R<Void> updateDetectElectricOpen(@Validated @RequestBody com.intc.fishery.domain.bo.ReqTurnOpen request) {
|
||||
deviceSwitchService.updateElectricWarnOpen(request.getId(), request.getIsOpen());
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@ package com.intc.fishery.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.intc.fishery.domain.bo.ReqAddLinkedCtrl;
|
||||
import com.intc.fishery.domain.bo.ReqId;
|
||||
import com.intc.fishery.domain.bo.ReqLinkedCtrlOpen;
|
||||
import com.intc.fishery.domain.bo.ReqUpdateLinkedCtrl;
|
||||
import com.intc.fishery.domain.dto.PublicLinkedCtrl;
|
||||
import com.intc.common.excel.utils.ExcelUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@@ -39,7 +44,7 @@ public class LinkedCtrlController extends BaseController {
|
||||
/**
|
||||
* 查询溶解氧联动控制列表
|
||||
*/
|
||||
@SaCheckPermission("fishery:linkedCtrl:list")
|
||||
// @SaCheckPermission("fishery:linkedCtrl:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<LinkedCtrlVo> list(LinkedCtrlBo bo, PageQuery pageQuery) {
|
||||
return linkedCtrlService.queryPageList(bo, pageQuery);
|
||||
@@ -61,7 +66,7 @@ public class LinkedCtrlController extends BaseController {
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("fishery:linkedCtrl:query")
|
||||
// @SaCheckPermission("fishery:linkedCtrl:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<LinkedCtrlVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
@@ -95,11 +100,66 @@ public class LinkedCtrlController extends BaseController {
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@SaCheckPermission("fishery:linkedCtrl:remove")
|
||||
// @SaCheckPermission("fishery:linkedCtrl:remove")
|
||||
@Log(title = "溶解氧联动控制", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(linkedCtrlService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增联动控制
|
||||
*
|
||||
* @param request 新增联动控制请求
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Log(title = "溶解氧联动控制", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/add")
|
||||
public R<Void> addLinkedCtrl(@Validated @RequestBody ReqAddLinkedCtrl request) {
|
||||
linkedCtrlService.addLinkedCtrl(request);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改联动控制
|
||||
*
|
||||
* @param request 修改联动控制请求
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Log(title = "溶解氧联动控制", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/update")
|
||||
public R<Void> updateLinkedCtrl(@Validated @RequestBody ReqUpdateLinkedCtrl request) {
|
||||
linkedCtrlService.updateLinkedCtrl(request);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据设备ID查询所有联动控制
|
||||
*
|
||||
* @param request 设备ID请求对象
|
||||
* @return 联动控制列表
|
||||
*/
|
||||
// @SaCheckPermission("fishery:linkedCtrl:query")
|
||||
@PostMapping("/fetch")
|
||||
public R<List<PublicLinkedCtrl>> queryAllLinkedCtrl(@Validated @RequestBody ReqId request) {
|
||||
return R.ok(linkedCtrlService.queryAllLinkedCtrl(request.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联动控制开关
|
||||
*
|
||||
* @param request 设置开关请求
|
||||
* @return 操作结果
|
||||
*/
|
||||
// @SaCheckPermission("fishery:linkedCtrl:edit")
|
||||
@Log(title = "溶解氧联动控制", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/set_open")
|
||||
public R<Void> setLinkedOpen(@Validated @RequestBody ReqLinkedCtrlOpen request) {
|
||||
linkedCtrlService.setLinkedOpen(request);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.intc.fishery.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.intc.fishery.domain.vo.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
@@ -17,20 +18,15 @@ import com.intc.common.core.validate.AddGroup;
|
||||
import com.intc.common.core.validate.EditGroup;
|
||||
import com.intc.common.log.enums.BusinessType;
|
||||
import com.intc.common.excel.utils.ExcelUtil;
|
||||
import com.intc.fishery.domain.vo.PondVo;
|
||||
import com.intc.fishery.domain.bo.PondBo;
|
||||
import com.intc.fishery.domain.bo.ReqChangePond;
|
||||
import com.intc.fishery.service.IPondService;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
import com.intc.common.satoken.utils.LoginHelper;
|
||||
import com.intc.fishery.service.IAquUserService;
|
||||
import com.intc.fishery.domain.vo.AquUserVo;
|
||||
import com.intc.fishery.domain.bo.AquUserBo;
|
||||
import com.intc.system.service.ISysUserService;
|
||||
import com.intc.system.domain.vo.SysUserVo;
|
||||
import com.intc.fishery.domain.vo.PondDeviceListVo;
|
||||
import com.intc.fishery.domain.vo.DeviceVo;
|
||||
import com.intc.fishery.domain.vo.DeviceWithSwitchVo;
|
||||
import com.intc.fishery.domain.vo.DeviceSwitchVo;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.mapper.DeviceSwitchMapper;
|
||||
import com.intc.fishery.domain.Device;
|
||||
@@ -49,8 +45,6 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import com.intc.fishery.domain.LinkedCtrl;
|
||||
import com.intc.fishery.domain.vo.PublicPondMode1Vo;
|
||||
import com.intc.fishery.domain.vo.PondMode1WarnCodeInfo;
|
||||
import com.intc.fishery.mapper.DeviceErrorCodeMapper;
|
||||
import com.intc.fishery.domain.DeviceErrorCode;
|
||||
import com.intc.fishery.constant.DefineDeviceWarnCode;
|
||||
@@ -808,4 +802,146 @@ public class PondController extends BaseController {
|
||||
|
||||
return R.ok(listData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户塘口列表 - 模式2(仅返回ID和名称)
|
||||
* 返回用户所有塘口的ID和名称列表
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @return 塘口ID和名称列表
|
||||
*/
|
||||
@GetMapping("/list_mode2")
|
||||
public R<List<PublicPondIdNameVo>> getPondList2(
|
||||
@RequestParam("rootUserId") Long rootUserId) {
|
||||
|
||||
// 查询用户的所有塘口,只获取ID和名称
|
||||
List<Pond> ponds = pondMapper.selectList(
|
||||
new LambdaQueryWrapper<Pond>()
|
||||
.eq(Pond::getUserId, rootUserId)
|
||||
.select(Pond::getId, Pond::getPondName)
|
||||
.orderByDesc(Pond::getCreateTime)
|
||||
);
|
||||
|
||||
// 转换为VO列表
|
||||
List<PublicPondIdNameVo> list = ponds.stream()
|
||||
.map(pond -> {
|
||||
PublicPondIdNameVo vo = new PublicPondIdNameVo();
|
||||
vo.setId(pond.getId());
|
||||
vo.setPondName(pond.getPondName());
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改设备塘口
|
||||
* 将设备分配到指定塘口或从塘口移除
|
||||
*
|
||||
* @param rootUserId 用户ID
|
||||
* @param request 请求对象(包含设备ID和塘口ID)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/update_pond")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<Void> changePond(
|
||||
@RequestParam("rootUserId") Long rootUserId,
|
||||
@Validated @RequestBody ReqChangePond request) {
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getPondId,
|
||||
Device::getDeviceName, Device::getSerialNum)
|
||||
);
|
||||
|
||||
// 验证设备存在性和权限
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(rootUserId)) {
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 如果塘口没有变化,直接返回
|
||||
Long oldPondId = device.getPondId();
|
||||
Long newPondId = (request.getPondId() != null && request.getPondId() > 0) ? request.getPondId() : null;
|
||||
|
||||
if ((oldPondId == null && newPondId == null) ||
|
||||
(oldPondId != null && oldPondId.equals(newPondId))) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 如果设备原来有塘口,删除关联的联动控制
|
||||
if (oldPondId != null) {
|
||||
linkedCtrlMapper.delete(
|
||||
new LambdaQueryWrapper<LinkedCtrl>()
|
||||
.eq(LinkedCtrl::getDeviceId, request.getId())
|
||||
);
|
||||
}
|
||||
|
||||
// 情凵1:分配或转移到新塘口
|
||||
if (newPondId != null) {
|
||||
// 验证塘口存在性和权限
|
||||
Pond pond = pondMapper.selectOne(
|
||||
new LambdaQueryWrapper<Pond>()
|
||||
.eq(Pond::getId, newPondId)
|
||||
.select(Pond::getId, Pond::getUserId, Pond::getPondName)
|
||||
);
|
||||
|
||||
if (pond == null || !pond.getUserId().equals(rootUserId)) {
|
||||
return R.fail("塘口不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 更新设备的塘口,并清除告警状态
|
||||
deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getPondId, newPondId)
|
||||
.set(Device::getIsTempWarnExist, 0)
|
||||
.set(Device::getIsOxygenWarnExist, 0)
|
||||
);
|
||||
|
||||
// TODO: 记录操作日志
|
||||
// if (oldPondId != null) {
|
||||
// // 转移到塘口
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),转移到塘口:%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(), pond.getPondName()));
|
||||
// } else {
|
||||
// // 分配塘口
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s),分配塘口:%s。",
|
||||
// device.getDeviceName(), device.getSerialNum(), pond.getPondName()));
|
||||
// }
|
||||
}
|
||||
// 情凵2:从塘口移除
|
||||
else {
|
||||
// 更新设备,移除塘口关联,并清除告警状态
|
||||
deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getPondId, null)
|
||||
.set(Device::getIsTempWarnExist, 0)
|
||||
.set(Device::getIsOxygenWarnExist, 0)
|
||||
);
|
||||
|
||||
// TODO: 记录操作日志
|
||||
// if (oldPondId != null) {
|
||||
// // 需要查询原塘口名称
|
||||
// Pond oldPond = pondMapper.selectById(oldPondId);
|
||||
// if (oldPond != null) {
|
||||
// CacheData.AddMessageOpRecordUser(rootUserId, userId, "设备操作",
|
||||
// String.format("%s(%s) 从 %s 移除。",
|
||||
// device.getDeviceName(), device.getSerialNum(), oldPond.getPondName()));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO: 清除设备报警等待和通知数据
|
||||
// await EventHelper.RemoveDeviceWarnWaitAndNotice(request.getId(),
|
||||
// DefineDeviceWarnCode.DetectorOxyOffline | DefineDeviceWarnCode.DetectorPHOffline |
|
||||
// DefineDeviceWarnCode.DetectorSalinityOffline);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 新增联动控制请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqAddLinkedCtrl implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 开关ID列表
|
||||
*/
|
||||
@NotEmpty(message = "开关ID列表不能为空")
|
||||
private List<Long> listSwitchId;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 修改设备名称请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "修改设备名称请求对象")
|
||||
public class ReqChangeName implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新名称
|
||||
*/
|
||||
@Schema(description = "新名称")
|
||||
@NotBlank(message = "新名称不能为空")
|
||||
@Size(max = 10, message = "名称长度不能超过10个字符")
|
||||
private String newName;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 修改设备塘口请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "修改设备塘口请求对象")
|
||||
public class ReqChangePond implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 塘口ID(为null或0表示移除塘口)
|
||||
*/
|
||||
@Schema(description = "塘口ID(为null或0表示移除塘口)")
|
||||
private Long pondId;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备校准请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqDeviceCalibrate implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 校准码
|
||||
*/
|
||||
@NotNull(message = "校准码不能为空")
|
||||
private String code;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置盐度补偿请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqDeviceSalinityCompensation implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 盐度补偿值
|
||||
*/
|
||||
@NotNull(message = "盐度补偿值不能为空")
|
||||
private Double salinityCompensation;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* ID请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqId implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@NotNull(message = "ID不能为空")
|
||||
private Long id;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置联动控制开关请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqLinkedCtrlOpen implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 联动控制ID
|
||||
*/
|
||||
@NotNull(message = "联动控制ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 开关类型(1-上限开关,2-下限开关)
|
||||
*/
|
||||
@NotNull(message = "开关类型不能为空")
|
||||
private Integer openType;
|
||||
|
||||
/**
|
||||
* 是否开启(0-关闭,1-开启)
|
||||
*/
|
||||
@NotNull(message = "开关状态不能为空")
|
||||
private Integer isOpen;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置溶解氧/温度告警开关请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqSetOxyTempWarnCall implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 类型(1-溶解氧告警,2-温度告警)
|
||||
*/
|
||||
@NotNull(message = "类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 是否打开告警开关
|
||||
*/
|
||||
@NotNull(message = "告警开关不能为空")
|
||||
private Integer isOpen;
|
||||
|
||||
/**
|
||||
* 是否开启免打扰
|
||||
*/
|
||||
@NotNull(message = "免打扰开关不能为空")
|
||||
private Integer isNoDisturb;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置溶解氧告警值请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqSetOxyWarnValue implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 溶解氧下限告警值
|
||||
*/
|
||||
@NotNull(message = "溶解氧下限告警值不能为空")
|
||||
private Double oxyWarnLower;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置温度告警值请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqSetTempWarnValue implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 温度上限告警值
|
||||
*/
|
||||
@NotNull(message = "温度上限告警值不能为空")
|
||||
private Double tempWarnUpper;
|
||||
|
||||
/**
|
||||
* 温度下限告警值
|
||||
*/
|
||||
@NotNull(message = "温度下限告警值不能为空")
|
||||
private Double tempWarnLower;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置开关电压类型请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqSetVoltageType implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开关ID
|
||||
*/
|
||||
@NotNull(message = "开关ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 电压类型(1-单相220V,4-三相380V四线)
|
||||
*/
|
||||
@NotNull(message = "电压类型不能为空")
|
||||
private Integer voltageType;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置开关额定电流请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqSwitchElectricSet implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开关ID
|
||||
*/
|
||||
@NotNull(message = "开关ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 额定电流值(单位:A)
|
||||
*/
|
||||
@NotNull(message = "额定电流值不能为空")
|
||||
private Double electric;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 开关设置请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqTurnOpen implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 是否开启(0-关闭,1-开启)
|
||||
*/
|
||||
@NotNull(message = "开关状态不能为空")
|
||||
private Integer isOpen;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.intc.fishery.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 修改联动控制请求对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class ReqUpdateLinkedCtrl implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 联动控制ID
|
||||
*/
|
||||
@NotNull(message = "联动控制ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 溶解氧上限值
|
||||
*/
|
||||
@NotNull(message = "溶解氧上限值不能为空")
|
||||
private Double oxyWarnUpper;
|
||||
|
||||
/**
|
||||
* 溶解氧下限值
|
||||
*/
|
||||
@NotNull(message = "溶解氧下限值不能为空")
|
||||
private Double oxyWarnLower;
|
||||
|
||||
/**
|
||||
* 开关ID列表
|
||||
*/
|
||||
@NotEmpty(message = "开关ID列表不能为空")
|
||||
private List<Long> listSwitchId;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备简单信息DTO
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceSimpleDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private Integer deviceType;
|
||||
|
||||
/**
|
||||
* 开关列表
|
||||
*/
|
||||
private List<PublicDeviceSwitchSimpleDto> listSwitch;
|
||||
|
||||
/**
|
||||
* 设备告警状态码
|
||||
*/
|
||||
private Integer warnCode;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.intc.common.json.handler.DoubleSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 开关基础数据DTO
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceSwitchBaseData implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开关ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 开关名称
|
||||
*/
|
||||
private String switchName;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 塘口信息
|
||||
*/
|
||||
private PublicPondIdName pondInfo;
|
||||
|
||||
/**
|
||||
* 当前测定电流
|
||||
*/
|
||||
@JsonSerialize(using = DoubleSerializer.class)
|
||||
private Double detectElectricValue;
|
||||
|
||||
/**
|
||||
* 当前测定电压
|
||||
*/
|
||||
@JsonSerialize(using = DoubleSerializer.class)
|
||||
private Double detectVoltageValue;
|
||||
|
||||
/**
|
||||
* 输入额定电压
|
||||
*/
|
||||
private Integer inputVoltage;
|
||||
|
||||
/**
|
||||
* 接线方式
|
||||
*/
|
||||
private Integer connectVoltageType;
|
||||
|
||||
/**
|
||||
* 电流告警开关
|
||||
*/
|
||||
private Integer electricWarnOpen;
|
||||
|
||||
/**
|
||||
* 额定电流设置
|
||||
*/
|
||||
@JsonSerialize(using = DoubleSerializer.class)
|
||||
private Double rateElectricValue;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备开关简单信息DTO(用于联动控制)
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceSwitchSimple implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开关ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 开关名称
|
||||
*/
|
||||
private String switchName;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备开关简单信息DTO
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceSwitchSimpleDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 开关ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private Integer index;
|
||||
|
||||
/**
|
||||
* 开关名称
|
||||
*/
|
||||
private String switchName;
|
||||
|
||||
/**
|
||||
* 联动控制ID
|
||||
*/
|
||||
private Long linkedCtrlId;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 联动控制信息DTO
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicLinkedCtrl implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 联动控制ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 溶解氧上限开关
|
||||
*/
|
||||
private Integer oxyUpperOpen;
|
||||
|
||||
/**
|
||||
* 溶解氧上限值
|
||||
*/
|
||||
private Double oxyUpperValue;
|
||||
|
||||
/**
|
||||
* 溶解氧下限开关
|
||||
*/
|
||||
private Integer oxyLowerOpen;
|
||||
|
||||
/**
|
||||
* 溶解氧下限值
|
||||
*/
|
||||
private Double oxyLowerValue;
|
||||
|
||||
/**
|
||||
* 开关列表
|
||||
*/
|
||||
private List<PublicDeviceSwitchSimple> listSwitch;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.intc.fishery.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 塘口ID和名称DTO
|
||||
*
|
||||
* @author intc
|
||||
* @date 2025-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicPondIdName implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 塘口ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 塘口名称
|
||||
*/
|
||||
private String pondName;
|
||||
}
|
||||
@@ -164,4 +164,34 @@ public class DeviceSwitchVo implements Serializable {
|
||||
*/
|
||||
private Boolean hasErrorCode;
|
||||
|
||||
/**
|
||||
* 设备到期时间(关联查询用)
|
||||
*/
|
||||
private Date deadTime;
|
||||
|
||||
/**
|
||||
* 设备告警状态码(关联查询用)
|
||||
*/
|
||||
private Integer warnCode;
|
||||
|
||||
/**
|
||||
* 设备IoT ID(关联查询用)
|
||||
*/
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 设备所属用户ID(关联查询用)
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 设备类型(关联查询用)
|
||||
*/
|
||||
private Integer deviceType;
|
||||
|
||||
/**
|
||||
* 设备输入电压类型(关联查询用)
|
||||
*/
|
||||
private Integer inputVoltage;
|
||||
|
||||
}
|
||||
|
||||
@@ -109,5 +109,24 @@ public class LinkedCtrlVo implements Serializable {
|
||||
@ExcelProperty(value = "用户名")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户ID(关联查询用)
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 塘口ID(关联查询用)
|
||||
*/
|
||||
private Long pondId;
|
||||
|
||||
/**
|
||||
* 设备告警状态码(关联查询用)
|
||||
*/
|
||||
private Integer warnCode;
|
||||
|
||||
/**
|
||||
* 设备到期时间(关联查询用)
|
||||
*/
|
||||
private java.util.Date deadTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.intc.fishery.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备基础数据视图对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceBaseData implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
private String serialNum;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private Integer deviceType;
|
||||
|
||||
/**
|
||||
* 绑定时间
|
||||
*/
|
||||
private Date bindTime;
|
||||
|
||||
/**
|
||||
* 服务到期时间
|
||||
*/
|
||||
private Date deadTime;
|
||||
|
||||
/**
|
||||
* 塘口信息
|
||||
*/
|
||||
private PublicPondIdNameVo pondInfo;
|
||||
|
||||
/**
|
||||
* 溶解氧参数配置开关
|
||||
*/
|
||||
private Integer isOxygenUsed;
|
||||
|
||||
/**
|
||||
* 溶解氧电话告警开关
|
||||
*/
|
||||
private Integer oxyWarnTelOpen;
|
||||
|
||||
/**
|
||||
* 低溶氧告警免打扰
|
||||
*/
|
||||
private Integer oxyWarnTelNoDis;
|
||||
|
||||
/**
|
||||
* 溶解氧电话告警下限
|
||||
*/
|
||||
private Double oxyWarnLower;
|
||||
|
||||
/**
|
||||
* 温度电话告警开关
|
||||
*/
|
||||
private Integer tempWarnTelOpen;
|
||||
|
||||
/**
|
||||
* 温度告警免打扰
|
||||
*/
|
||||
private Integer tempWarnTelNoDis;
|
||||
|
||||
/**
|
||||
* 温度电话告警上限
|
||||
*/
|
||||
private Double tempWarnUpper;
|
||||
|
||||
/**
|
||||
* 温度电话告警下限
|
||||
*/
|
||||
private Double tempWarnLower;
|
||||
|
||||
/**
|
||||
* 盐度补偿
|
||||
*/
|
||||
private Double salinityCompensation;
|
||||
|
||||
/**
|
||||
* 输入额定电压
|
||||
*/
|
||||
private Integer inputVoltage;
|
||||
|
||||
/**
|
||||
* 电压告警开关
|
||||
*/
|
||||
private Integer voltageWarnOpen;
|
||||
|
||||
/**
|
||||
* 开关列表(仅测控一体机)
|
||||
*/
|
||||
private List<PublicDeviceSwitchSimpleVo> listSwitch;
|
||||
|
||||
/**
|
||||
* 联动控制列表
|
||||
*/
|
||||
private List<PublicDeviceLinkedCtrl> listLinkedCtr;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.intc.fishery.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 设备到期信息视图对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "设备到期信息")
|
||||
public class PublicDeviceDeadInfo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@Schema(description = "设备名称")
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 设备序列号
|
||||
*/
|
||||
@Schema(description = "设备序列号")
|
||||
private String serialNum;
|
||||
|
||||
/**
|
||||
* 服务到期时间
|
||||
*/
|
||||
@Schema(description = "服务到期时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date deadTime;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.intc.fishery.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备联动控制视图对象
|
||||
*
|
||||
* @author intc
|
||||
* @date 2026-01-13
|
||||
*/
|
||||
@Data
|
||||
public class PublicDeviceLinkedCtrl implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 联动控制ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private Long deviceId;
|
||||
|
||||
/**
|
||||
* 溶解氧上限开关
|
||||
*/
|
||||
private Integer oxyUpperOpen;
|
||||
|
||||
/**
|
||||
* 溶解氧上限值
|
||||
*/
|
||||
private Double oxyUpperValue;
|
||||
|
||||
/**
|
||||
* 溶解氧下限开关
|
||||
*/
|
||||
private Integer oxyLowerOpen;
|
||||
|
||||
/**
|
||||
* 溶解氧下限值
|
||||
*/
|
||||
private Double oxyLowerValue;
|
||||
|
||||
/**
|
||||
* 关联的开关列表
|
||||
*/
|
||||
private List<PublicDeviceSwitchSimpleVo> listSwitch;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.intc.fishery.service;
|
||||
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSimpleDto;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSwitchBaseData;
|
||||
import com.intc.fishery.domain.vo.DeviceSwitchVo;
|
||||
import com.intc.fishery.domain.bo.DeviceSwitchBo;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -65,4 +67,36 @@ public interface IDeviceSwitchService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 根据塘口ID查询塘口下的设备及其开关信息
|
||||
*
|
||||
* @param pondId 塘口ID
|
||||
* @return 设备及开关列表
|
||||
*/
|
||||
List<PublicDeviceSimpleDto> getPondSwitch(Long pondId);
|
||||
|
||||
/**
|
||||
* 获取单个开关的基础信息
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @return 开关基础信息
|
||||
*/
|
||||
PublicDeviceSwitchBaseData getOneSwitchInfo(Long switchId);
|
||||
|
||||
/**
|
||||
* 修改开关名称
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @param newName 新名称
|
||||
*/
|
||||
void changeSwitchName(Long switchId, String newName);
|
||||
|
||||
/**
|
||||
* 设置电流告警开关
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @param isOpen 是否开启(0-关闭,1-开启)
|
||||
*/
|
||||
void updateElectricWarnOpen(Long switchId, Integer isOpen);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.intc.fishery.service;
|
||||
|
||||
import com.intc.fishery.domain.bo.ReqAddLinkedCtrl;
|
||||
import com.intc.fishery.domain.bo.ReqLinkedCtrlOpen;
|
||||
import com.intc.fishery.domain.bo.ReqUpdateLinkedCtrl;
|
||||
import com.intc.fishery.domain.dto.PublicLinkedCtrl;
|
||||
import com.intc.fishery.domain.vo.LinkedCtrlVo;
|
||||
import com.intc.fishery.domain.bo.LinkedCtrlBo;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -65,4 +69,33 @@ public interface ILinkedCtrlService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 新增联动控制(业务方法)
|
||||
*
|
||||
* @param request 新增联动控制请求
|
||||
*/
|
||||
void addLinkedCtrl(ReqAddLinkedCtrl request);
|
||||
|
||||
/**
|
||||
* 修改联动控制(业务方法)
|
||||
*
|
||||
* @param request 修改联动控制请求
|
||||
*/
|
||||
void updateLinkedCtrl(ReqUpdateLinkedCtrl request);
|
||||
|
||||
/**
|
||||
* 根据设备ID查询所有联动控制
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 联动控制列表
|
||||
*/
|
||||
List<PublicLinkedCtrl> queryAllLinkedCtrl(Long deviceId);
|
||||
|
||||
/**
|
||||
* 设置联动控制开关
|
||||
*
|
||||
* @param request 设置开关请求
|
||||
*/
|
||||
void setLinkedOpen(ReqLinkedCtrlOpen request);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,13 @@ import com.intc.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSimpleDto;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSwitchSimpleDto;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSwitchBaseData;
|
||||
import com.intc.fishery.domain.dto.PublicPondIdName;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.intc.fishery.domain.bo.DeviceSwitchBo;
|
||||
import com.intc.fishery.domain.vo.DeviceSwitchVo;
|
||||
@@ -17,12 +22,13 @@ import com.intc.fishery.domain.DeviceSwitch;
|
||||
import com.intc.fishery.domain.Device;
|
||||
import com.intc.fishery.domain.Pond;
|
||||
import com.intc.fishery.domain.AquUser;
|
||||
import com.intc.fishery.domain.TimingCtrl;
|
||||
import com.intc.fishery.mapper.DeviceSwitchMapper;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.service.IDeviceSwitchService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 测控一体机开关Service业务层处理
|
||||
@@ -36,6 +42,7 @@ import java.util.Collection;
|
||||
public class DeviceSwitchServiceImpl implements IDeviceSwitchService {
|
||||
|
||||
private final DeviceSwitchMapper baseMapper;
|
||||
private final DeviceMapper deviceMapper;
|
||||
|
||||
/**
|
||||
* 查询测控一体机开关
|
||||
@@ -223,4 +230,221 @@ public class DeviceSwitchServiceImpl implements IDeviceSwitchService {
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据塘口ID查询塘口下的设备及其开关信息
|
||||
*
|
||||
* @param pondId 塘口ID
|
||||
* @return 设备及开关列表
|
||||
*/
|
||||
@Override
|
||||
public List<PublicDeviceSimpleDto> getPondSwitch(Long pondId) {
|
||||
// 使用连表查询获取该塘口下的所有开关及其关联的设备信息
|
||||
MPJLambdaWrapper<DeviceSwitch> wrapper = new MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, DeviceSwitchVo::getDeviceName)
|
||||
.selectAs(Device::getWarnCode, DeviceSwitchVo::getWarnCode)
|
||||
.selectAs(Device::getDeadTime, "deadTime")
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.eq(DeviceSwitch::getPondId, pondId)
|
||||
.orderByAsc(DeviceSwitch::getIndex);
|
||||
|
||||
List<DeviceSwitchVo> switchList = baseMapper.selectJoinList(DeviceSwitchVo.class, wrapper);
|
||||
|
||||
// 过滤掉已过期的设备,并按设备分组
|
||||
Map<Long, List<DeviceSwitchVo>> deviceSwitchMap = switchList.stream()
|
||||
.filter(vo -> !isDeviceDead(vo))
|
||||
.collect(Collectors.groupingBy(DeviceSwitchVo::getDeviceId));
|
||||
|
||||
// 构建返回结果
|
||||
List<PublicDeviceSimpleDto> result = new ArrayList<>();
|
||||
for (Map.Entry<Long, List<DeviceSwitchVo>> entry : deviceSwitchMap.entrySet()) {
|
||||
List<DeviceSwitchVo> switches = entry.getValue();
|
||||
if (switches.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 从第一个开关记录中获取设备信息
|
||||
DeviceSwitchVo firstSwitch = switches.get(0);
|
||||
|
||||
PublicDeviceSimpleDto deviceDto = new PublicDeviceSimpleDto();
|
||||
deviceDto.setId(entry.getKey());
|
||||
deviceDto.setDeviceName(firstSwitch.getDeviceName());
|
||||
deviceDto.setDeviceType(1); // 测控一体机设备类型设为1(Controller)
|
||||
deviceDto.setWarnCode(firstSwitch.getWarnCode());
|
||||
|
||||
// 转换开关列表
|
||||
List<PublicDeviceSwitchSimpleDto> switchDtoList = switches.stream()
|
||||
.map(this::convertToSwitchDto)
|
||||
.collect(Collectors.toList());
|
||||
deviceDto.setListSwitch(switchDtoList);
|
||||
|
||||
result.add(deviceDto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断设备是否已过期
|
||||
*
|
||||
* @param vo 设备开关信息
|
||||
* @return true-已过期,false-未过期
|
||||
*/
|
||||
private boolean isDeviceDead(DeviceSwitchVo vo) {
|
||||
Date deadTime = vo.getDeadTime();
|
||||
if (deadTime == null) {
|
||||
return false;
|
||||
}
|
||||
return deadTime.before(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将DeviceSwitchVo转换为PublicDeviceSwitchSimpleDto
|
||||
*
|
||||
* @param vo 设备开关VO
|
||||
* @return 设备开关简单DTO
|
||||
*/
|
||||
private PublicDeviceSwitchSimpleDto convertToSwitchDto(DeviceSwitchVo vo) {
|
||||
PublicDeviceSwitchSimpleDto dto = new PublicDeviceSwitchSimpleDto();
|
||||
dto.setId(vo.getId());
|
||||
dto.setIndex(vo.getIndex());
|
||||
dto.setSwitchName(vo.getSwitchName());
|
||||
dto.setLinkedCtrlId(vo.getLinkedCtrlId() != null ? vo.getLinkedCtrlId() : 0L);
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个开关的基础信息
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @return 开关基础信息
|
||||
*/
|
||||
@Override
|
||||
public PublicDeviceSwitchBaseData getOneSwitchInfo(Long switchId) {
|
||||
// 使用连表查询获取开关及其关联的设备和塘口信息
|
||||
MPJLambdaWrapper<DeviceSwitch> wrapper = new MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getInputVoltage, "inputVoltage")
|
||||
.selectAs(Pond::getPondName, "pondName")
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.leftJoin(Pond.class, Pond::getId, DeviceSwitch::getPondId)
|
||||
.eq(DeviceSwitch::getId, switchId);
|
||||
|
||||
DeviceSwitchVo vo = baseMapper.selectJoinOne(DeviceSwitchVo.class, wrapper);
|
||||
if (vo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 转换为返回DTO
|
||||
PublicDeviceSwitchBaseData data = new PublicDeviceSwitchBaseData();
|
||||
data.setId(vo.getId());
|
||||
data.setIndex(vo.getIndex());
|
||||
data.setSwitchName(vo.getSwitchName());
|
||||
data.setDeviceName(vo.getDeviceName());
|
||||
data.setDetectElectricValue(vo.getDetectElectricValue());
|
||||
data.setDetectVoltageValue(vo.getDetectVoltageValue());
|
||||
data.setConnectVoltageType(vo.getConnectVoltageType());
|
||||
data.setElectricWarnOpen(vo.getElectricWarnOpen());
|
||||
data.setRateElectricValue(vo.getRateElectricValue());
|
||||
|
||||
// 从连表查询结果中获取inputVoltage
|
||||
Integer inputVoltage = null;
|
||||
if (vo.getDeviceId() != null) {
|
||||
Device device = deviceMapper.selectById(vo.getDeviceId());
|
||||
if (device != null) {
|
||||
inputVoltage = device.getInputVoltage();
|
||||
}
|
||||
}
|
||||
data.setInputVoltage(inputVoltage);
|
||||
|
||||
// 设置塘口信息
|
||||
if (vo.getPondId() != null && StringUtils.isNotBlank(vo.getPondName())) {
|
||||
PublicPondIdName pondInfo = new PublicPondIdName();
|
||||
pondInfo.setId(vo.getPondId());
|
||||
pondInfo.setPondName(vo.getPondName());
|
||||
data.setPondInfo(pondInfo);
|
||||
}
|
||||
|
||||
// 如果接线方式为4,需要将电压值乘以1.732
|
||||
if (data.getConnectVoltageType() != null && data.getConnectVoltageType() == 4 && data.getDetectVoltageValue() != null) {
|
||||
data.setDetectVoltageValue(data.getDetectVoltageValue() * 1.732);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改开关名称
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @param newName 新名称
|
||||
*/
|
||||
@Override
|
||||
public void changeSwitchName(Long switchId, String newName) {
|
||||
// 查询开关信息,包括关联的设备信息
|
||||
MPJLambdaWrapper<DeviceSwitch> wrapper = new MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.eq(DeviceSwitch::getId, switchId);
|
||||
|
||||
DeviceSwitchVo vo = baseMapper.selectJoinOne(DeviceSwitchVo.class, wrapper);
|
||||
if (vo == null) {
|
||||
throw new RuntimeException("开关不存在");
|
||||
}
|
||||
|
||||
String oldName = vo.getSwitchName();
|
||||
|
||||
// 更新开关名称
|
||||
DeviceSwitch updateEntity = new DeviceSwitch();
|
||||
updateEntity.setId(switchId);
|
||||
updateEntity.setSwitchName(newName);
|
||||
baseMapper.updateById(updateEntity);
|
||||
|
||||
// 记录操作日志
|
||||
log.info("开关操作:{}({})的开关{}修改名称为:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), oldName, newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置电流告警开关
|
||||
*
|
||||
* @param switchId 开关ID
|
||||
* @param isOpen 是否开启(0-关闭,1-开启)
|
||||
*/
|
||||
@Override
|
||||
public void updateElectricWarnOpen(Long switchId, Integer isOpen) {
|
||||
// 查询开关信息,包括关联的设备信息
|
||||
MPJLambdaWrapper<DeviceSwitch> wrapper = new MPJLambdaWrapper<DeviceSwitch>()
|
||||
.selectAll(DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getUserId, "userId")
|
||||
.leftJoin(Device.class, Device::getId, DeviceSwitch::getDeviceId)
|
||||
.eq(DeviceSwitch::getId, switchId);
|
||||
|
||||
DeviceSwitchVo vo = baseMapper.selectJoinOne(DeviceSwitchVo.class, wrapper);
|
||||
if (vo == null || vo.getUserId() == null) {
|
||||
throw new RuntimeException("开关不存在");
|
||||
}
|
||||
|
||||
// 如果状态未变化,无需更新
|
||||
if (vo.getElectricWarnOpen() != null && vo.getElectricWarnOpen().equals(isOpen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新电流告警开关状态
|
||||
DeviceSwitch updateEntity = new DeviceSwitch();
|
||||
updateEntity.setId(switchId);
|
||||
updateEntity.setElectricWarnOpen(isOpen);
|
||||
baseMapper.updateById(updateEntity);
|
||||
|
||||
// 记录操作日志
|
||||
String operation = isOpen == 1 ? "开启" : "关闭";
|
||||
log.info("开关操作:{}({})的开关{},设置电流告警开关:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), operation);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.intc.fishery.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.intc.common.core.exception.ServiceException;
|
||||
import com.intc.common.core.utils.MapstructUtils;
|
||||
import com.intc.common.core.utils.StringUtils;
|
||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -9,7 +11,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.intc.fishery.domain.*;
|
||||
import com.intc.fishery.domain.bo.ReqAddLinkedCtrl;
|
||||
import com.intc.fishery.domain.bo.ReqLinkedCtrlOpen;
|
||||
import com.intc.fishery.domain.bo.ReqUpdateLinkedCtrl;
|
||||
import com.intc.fishery.domain.dto.PublicDeviceSwitchSimple;
|
||||
import com.intc.fishery.domain.dto.PublicLinkedCtrl;
|
||||
import com.intc.fishery.domain.vo.DeviceSwitchVo;
|
||||
import com.intc.fishery.mapper.DeviceMapper;
|
||||
import com.intc.fishery.mapper.DeviceSwitchMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -17,10 +26,10 @@ import com.intc.fishery.domain.bo.LinkedCtrlBo;
|
||||
import com.intc.fishery.domain.vo.LinkedCtrlVo;
|
||||
import com.intc.fishery.mapper.LinkedCtrlMapper;
|
||||
import com.intc.fishery.service.ILinkedCtrlService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 溶解氧联动控制Service业务层处理
|
||||
@@ -34,6 +43,8 @@ import java.util.Collection;
|
||||
public class LinkedCtrlServiceImpl implements ILinkedCtrlService {
|
||||
|
||||
private final LinkedCtrlMapper baseMapper;
|
||||
private final DeviceMapper deviceMapper;
|
||||
private final DeviceSwitchMapper deviceSwitchMapper;
|
||||
|
||||
/**
|
||||
* 查询溶解氧联动控制
|
||||
@@ -191,10 +202,351 @@ public class LinkedCtrlServiceImpl implements ILinkedCtrlService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
|
||||
// 删除联动控制前,先解除关联的开关绑定
|
||||
deviceSwitchMapper.update(null,
|
||||
Wrappers.lambdaUpdate(DeviceSwitch.class)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, null)
|
||||
.in(DeviceSwitch::getLinkedCtrlId, ids));
|
||||
|
||||
// 删除联动控制记录
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增联动控制(业务方法)
|
||||
*
|
||||
* @param request 新增联动控制请求
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void addLinkedCtrl(ReqAddLinkedCtrl request) {
|
||||
// 1. 检查该设备的联动控制数量是否超过3个
|
||||
long count = baseMapper.selectCount(Wrappers.lambdaQuery(LinkedCtrl.class)
|
||||
.eq(LinkedCtrl::getDeviceId, request.getDeviceId()));
|
||||
if (count >= 3) {
|
||||
throw new ServiceException("联动控制数量不得超过3个");
|
||||
}
|
||||
|
||||
// 2. 查询设备信息
|
||||
Device device = deviceMapper.selectOne(Wrappers.lambdaQuery(Device.class)
|
||||
.eq(Device::getId, request.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getPondId,
|
||||
Device::getDeviceName, Device::getSerialNum, Device::getWarnCode, Device::getDeadTime));
|
||||
|
||||
if (device == null) {
|
||||
throw new ServiceException("设备不存在");
|
||||
}
|
||||
|
||||
// 3. 检查设备是否过期
|
||||
if (isDeviceDead(device)) {
|
||||
throw new ServiceException("设备已过期");
|
||||
}
|
||||
|
||||
// 4. 检查设备是否已绑定塘口
|
||||
if (device.getPondId() == null) {
|
||||
throw new ServiceException("设备未绑定塘口");
|
||||
}
|
||||
|
||||
Long pondId = device.getPondId();
|
||||
|
||||
// 5. 验证开关是否属于该塘口
|
||||
long matchCount = deviceSwitchMapper.selectCount(Wrappers.lambdaQuery(DeviceSwitch.class)
|
||||
.eq(DeviceSwitch::getPondId, pondId)
|
||||
.in(DeviceSwitch::getId, request.getListSwitchId()));
|
||||
if (matchCount != request.getListSwitchId().size()) {
|
||||
throw new ServiceException("开关不属于该塘口");
|
||||
}
|
||||
|
||||
// 6. 创建联动控制记录
|
||||
LinkedCtrl linkedCtrl = new LinkedCtrl();
|
||||
linkedCtrl.setDeviceId(request.getDeviceId());
|
||||
linkedCtrl.setOxyUpperOpen(0); // 默认关闭
|
||||
linkedCtrl.setOxyUpperValue(10.0);
|
||||
linkedCtrl.setIsOxyUpperTrigger(0);
|
||||
linkedCtrl.setOxyLowerOpen(0); // 默认关闭
|
||||
linkedCtrl.setOxyLowerValue(5.0);
|
||||
|
||||
int inserted = baseMapper.insert(linkedCtrl);
|
||||
if (inserted == 0) {
|
||||
throw new ServiceException("新增联动控制失败");
|
||||
}
|
||||
|
||||
Long linkedCtrlId = linkedCtrl.getId();
|
||||
|
||||
// 7. 更新开关的linkedCtrlId
|
||||
int updated = deviceSwitchMapper.update(null,
|
||||
Wrappers.lambdaUpdate(DeviceSwitch.class)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, linkedCtrlId)
|
||||
.in(DeviceSwitch::getId, request.getListSwitchId()));
|
||||
|
||||
if (updated == 0) {
|
||||
throw new ServiceException("请选择联动控制开关");
|
||||
}
|
||||
|
||||
log.info("设备{}({})新增联动控制", device.getDeviceName(), device.getSerialNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改联动控制(业务方法)
|
||||
*
|
||||
* @param request 修改联动控制请求
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateLinkedCtrl(ReqUpdateLinkedCtrl request) {
|
||||
// 1. 验证溶解氧上下限值
|
||||
if (request.getOxyWarnUpper() < request.getOxyWarnLower() + 1.0) {
|
||||
throw new ServiceException("溶解氧上限值必须大于下限值1以上");
|
||||
}
|
||||
|
||||
// 2. 查询联动控制信息(包括设备信息)
|
||||
MPJLambdaWrapper<LinkedCtrl> wrapper = new MPJLambdaWrapper<LinkedCtrl>()
|
||||
.selectAll(LinkedCtrl.class)
|
||||
.selectAs(Device::getUserId, LinkedCtrlVo::getUserId)
|
||||
.selectAs(Device::getPondId, LinkedCtrlVo::getPondId)
|
||||
.selectAs(Device::getDeviceName, LinkedCtrlVo::getDeviceName)
|
||||
.selectAs(Device::getSerialNum, LinkedCtrlVo::getSerialNum)
|
||||
.selectAs(Device::getWarnCode, LinkedCtrlVo::getWarnCode)
|
||||
.selectAs(Device::getDeadTime, LinkedCtrlVo::getDeadTime)
|
||||
.leftJoin(Device.class, Device::getId, LinkedCtrl::getDeviceId)
|
||||
.eq(LinkedCtrl::getId, request.getId());
|
||||
|
||||
LinkedCtrlVo linkedCtrlVo = baseMapper.selectJoinOne(LinkedCtrlVo.class, wrapper);
|
||||
|
||||
if (linkedCtrlVo == null) {
|
||||
throw new ServiceException("联动控制不存在");
|
||||
}
|
||||
|
||||
// 3. 查询设备信息用于过期检查
|
||||
Device device = deviceMapper.selectOne(Wrappers.lambdaQuery(Device.class)
|
||||
.eq(Device::getId, linkedCtrlVo.getDeviceId())
|
||||
.select(Device::getId, Device::getDeadTime, Device::getPondId,
|
||||
Device::getDeviceName, Device::getSerialNum));
|
||||
|
||||
if (device == null) {
|
||||
throw new ServiceException("设备不存在");
|
||||
}
|
||||
|
||||
// 4. 检查设备是否过期
|
||||
if (isDeviceDead(device)) {
|
||||
throw new ServiceException("设备已过期");
|
||||
}
|
||||
|
||||
// 5. 验证开关是否属于该塘口
|
||||
long matchCount = deviceSwitchMapper.selectCount(Wrappers.lambdaQuery(DeviceSwitch.class)
|
||||
.eq(DeviceSwitch::getPondId, device.getPondId())
|
||||
.in(DeviceSwitch::getId, request.getListSwitchId()));
|
||||
if (matchCount != request.getListSwitchId().size()) {
|
||||
throw new ServiceException("开关不属于该塘口");
|
||||
}
|
||||
|
||||
// 6. 查询当前联动控制已绑定的开关
|
||||
List<DeviceSwitch> currentSwitches = deviceSwitchMapper.selectList(
|
||||
Wrappers.lambdaQuery(DeviceSwitch.class)
|
||||
.eq(DeviceSwitch::getLinkedCtrlId, request.getId())
|
||||
.select(DeviceSwitch::getId));
|
||||
|
||||
List<Long> currentSwitchIds = currentSwitches.stream()
|
||||
.map(DeviceSwitch::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 找出需要移除绑定的开关(在旧列表中但不在新列表中)
|
||||
List<Long> switchesToRemove = currentSwitchIds.stream()
|
||||
.filter(id -> !request.getListSwitchId().contains(id))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 7. 更新联动控制的溶解氧上下限值
|
||||
baseMapper.update(null,
|
||||
Wrappers.lambdaUpdate(LinkedCtrl.class)
|
||||
.set(LinkedCtrl::getOxyUpperValue, request.getOxyWarnUpper())
|
||||
.set(LinkedCtrl::getOxyLowerValue, request.getOxyWarnLower())
|
||||
.eq(LinkedCtrl::getId, request.getId()));
|
||||
|
||||
// 8. 更新新开关的linkedCtrlId
|
||||
deviceSwitchMapper.update(null,
|
||||
Wrappers.lambdaUpdate(DeviceSwitch.class)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, request.getId())
|
||||
.in(DeviceSwitch::getId, request.getListSwitchId()));
|
||||
|
||||
// 9. 移除旧开关的linkedCtrlId
|
||||
if (!switchesToRemove.isEmpty()) {
|
||||
deviceSwitchMapper.update(null,
|
||||
Wrappers.lambdaUpdate(DeviceSwitch.class)
|
||||
.set(DeviceSwitch::getLinkedCtrlId, null)
|
||||
.in(DeviceSwitch::getId, switchesToRemove));
|
||||
}
|
||||
|
||||
log.info("设备{}({})修改联动控制", device.getDeviceName(), device.getSerialNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断设备是否已过期
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @return true-已过期,false-未过期
|
||||
*/
|
||||
private boolean isDeviceDead(Device device) {
|
||||
Date deadTime = device.getDeadTime();
|
||||
if (deadTime == null) {
|
||||
return false;
|
||||
}
|
||||
return deadTime.before(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据设备ID查询所有联动控制
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 联动控制列表
|
||||
*/
|
||||
@Override
|
||||
public List<PublicLinkedCtrl> queryAllLinkedCtrl(Long deviceId) {
|
||||
// 1. 查询该设备下的所有联动控制
|
||||
List<LinkedCtrl> linkedCtrls = baseMapper.selectList(
|
||||
Wrappers.lambdaQuery(LinkedCtrl.class)
|
||||
.eq(LinkedCtrl::getDeviceId, deviceId)
|
||||
.orderByAsc(LinkedCtrl::getId));
|
||||
|
||||
if (linkedCtrls.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 2. 收集所有联动控制ID
|
||||
List<Long> linkedCtrlIds = linkedCtrls.stream()
|
||||
.map(LinkedCtrl::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 3. 查询与这些联动控制相关的开关
|
||||
List<DeviceSwitch> switches = deviceSwitchMapper.selectList(
|
||||
Wrappers.lambdaQuery(DeviceSwitch.class)
|
||||
.in(DeviceSwitch::getLinkedCtrlId, linkedCtrlIds)
|
||||
.orderByAsc(DeviceSwitch::getIndex));
|
||||
|
||||
// 4. 按linkedCtrlId分组开关
|
||||
Map<Long, List<DeviceSwitch>> switchMap = switches.stream()
|
||||
.collect(Collectors.groupingBy(DeviceSwitch::getLinkedCtrlId));
|
||||
|
||||
// 5. 构建返回结果
|
||||
List<PublicLinkedCtrl> result = new ArrayList<>();
|
||||
for (LinkedCtrl linkedCtrl : linkedCtrls) {
|
||||
PublicLinkedCtrl dto = new PublicLinkedCtrl();
|
||||
dto.setId(linkedCtrl.getId());
|
||||
dto.setDeviceId(linkedCtrl.getDeviceId());
|
||||
dto.setOxyUpperOpen(linkedCtrl.getOxyUpperOpen());
|
||||
dto.setOxyUpperValue(linkedCtrl.getOxyUpperValue());
|
||||
dto.setOxyLowerOpen(linkedCtrl.getOxyLowerOpen());
|
||||
dto.setOxyLowerValue(linkedCtrl.getOxyLowerValue());
|
||||
|
||||
// 转换开关列表
|
||||
List<DeviceSwitch> linkedSwitches = switchMap.getOrDefault(linkedCtrl.getId(), new ArrayList<>());
|
||||
List<PublicDeviceSwitchSimple> switchDtos = linkedSwitches.stream()
|
||||
.map(this::convertToSwitchSimple)
|
||||
.collect(Collectors.toList());
|
||||
dto.setListSwitch(switchDtos);
|
||||
|
||||
result.add(dto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将DeviceSwitch转换为PublicDeviceSwitchSimple
|
||||
*
|
||||
* @param deviceSwitch 设备开关
|
||||
* @return 设备开关简单DTO
|
||||
*/
|
||||
private PublicDeviceSwitchSimple convertToSwitchSimple(DeviceSwitch deviceSwitch) {
|
||||
PublicDeviceSwitchSimple dto = new PublicDeviceSwitchSimple();
|
||||
dto.setId(deviceSwitch.getId());
|
||||
dto.setIndex(deviceSwitch.getIndex());
|
||||
dto.setSwitchName(deviceSwitch.getSwitchName());
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联动控制开关
|
||||
*
|
||||
* @param request 设置开关请求
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void setLinkedOpen(ReqLinkedCtrlOpen request) {
|
||||
// 1. 查询联动控制信息(包括设备信息)
|
||||
MPJLambdaWrapper<LinkedCtrl> wrapper = new MPJLambdaWrapper<LinkedCtrl>()
|
||||
.selectAll(LinkedCtrl.class)
|
||||
.selectAs(Device::getUserId, LinkedCtrlVo::getUserId)
|
||||
.selectAs(Device::getPondId, LinkedCtrlVo::getPondId)
|
||||
.selectAs(Device::getDeviceName, LinkedCtrlVo::getDeviceName)
|
||||
.selectAs(Device::getSerialNum, LinkedCtrlVo::getSerialNum)
|
||||
.selectAs(Device::getWarnCode, LinkedCtrlVo::getWarnCode)
|
||||
.selectAs(Device::getDeadTime, LinkedCtrlVo::getDeadTime)
|
||||
.leftJoin(Device.class, Device::getId, LinkedCtrl::getDeviceId)
|
||||
.eq(LinkedCtrl::getId, request.getId());
|
||||
|
||||
LinkedCtrlVo linkedCtrlVo = baseMapper.selectJoinOne(LinkedCtrlVo.class, wrapper);
|
||||
|
||||
if (linkedCtrlVo == null) {
|
||||
throw new ServiceException("联动控制不存在");
|
||||
}
|
||||
|
||||
// 2. 查询设备信息用于过期检查
|
||||
Device device = deviceMapper.selectOne(Wrappers.lambdaQuery(Device.class)
|
||||
.eq(Device::getId, linkedCtrlVo.getDeviceId())
|
||||
.select(Device::getId, Device::getDeadTime, Device::getDeviceName, Device::getSerialNum));
|
||||
|
||||
if (device == null) {
|
||||
throw new ServiceException("设备不存在");
|
||||
}
|
||||
|
||||
// 3. 检查设备是否过期
|
||||
if (isDeviceDead(device)) {
|
||||
throw new ServiceException("设备已过期");
|
||||
}
|
||||
|
||||
// 4. 根据开关类型设置对应的开关
|
||||
if (request.getOpenType() == 1) {
|
||||
// 上限开关
|
||||
if (linkedCtrlVo.getOxyUpperOpen().equals(request.getIsOpen())) {
|
||||
// 状态未变化,直接返回
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新上限开关状态和触发标志
|
||||
baseMapper.update(null,
|
||||
Wrappers.lambdaUpdate(LinkedCtrl.class)
|
||||
.set(LinkedCtrl::getOxyUpperOpen, request.getIsOpen())
|
||||
.set(LinkedCtrl::getIsOxyUpperTrigger, 0) // 重置触发标志
|
||||
.eq(LinkedCtrl::getId, request.getId()));
|
||||
|
||||
String op = request.getIsOpen() == 1 ? "开启" : "关闭";
|
||||
log.info("设备{}({})溶解氧上限联动控制:{}",
|
||||
device.getDeviceName(), device.getSerialNum(), op);
|
||||
|
||||
} else if (request.getOpenType() == 2) {
|
||||
// 下限开关
|
||||
if (linkedCtrlVo.getOxyLowerOpen().equals(request.getIsOpen())) {
|
||||
// 状态未变化,直接返回
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新下限开关状态
|
||||
baseMapper.update(null,
|
||||
Wrappers.lambdaUpdate(LinkedCtrl.class)
|
||||
.set(LinkedCtrl::getOxyLowerOpen, request.getIsOpen())
|
||||
.eq(LinkedCtrl::getId, request.getId()));
|
||||
|
||||
String op = request.getIsOpen() == 1 ? "开启" : "关闭";
|
||||
log.info("设备{}({})溶解氧下限联动控制:{}",
|
||||
device.getDeviceName(), device.getSerialNum(), op);
|
||||
} else {
|
||||
throw new ServiceException("无效的开关类型");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@ import com.intc.fishery.mapper.PondMapper;
|
||||
import com.intc.iot.config.AliyunIotProperties;
|
||||
import com.intc.iot.domain.bo.AddDeviceControllerBo;
|
||||
import com.intc.iot.domain.bo.AddDeviceDetectorBo;
|
||||
import com.intc.iot.domain.bo.DeviceCalibrateBo;
|
||||
import com.intc.iot.domain.bo.DeviceRealtimeDataBo;
|
||||
import com.intc.iot.domain.bo.DeviceSalinityCompensationBo;
|
||||
import com.intc.iot.domain.bo.DeviceVoltageTypeBo;
|
||||
import com.intc.iot.domain.vo.DeviceRealtimeDataVo;
|
||||
import com.intc.iot.service.DeviceDataService;
|
||||
import com.intc.iot.service.DeviceRealtimeDataService;
|
||||
@@ -22,6 +25,8 @@ import com.intc.iot.service.VmsMnsConsumerService;
|
||||
import com.intc.iot.service.VmsNoticeService;
|
||||
import com.intc.iot.service.WarnCallNoticeService;
|
||||
import com.intc.iot.utils.AliyunAmqpSignUtil;
|
||||
import com.intc.iot.utils.ControllerHelper;
|
||||
import com.intc.iot.service.IotCloudService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -83,6 +88,15 @@ public class IotController extends BaseController {
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.DeviceSwitchMapper deviceSwitchMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private com.intc.fishery.mapper.TimingCtrlMapper timingCtrlMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IotCloudService iotCloudService;
|
||||
|
||||
@Operation(summary = "测试接口")
|
||||
@GetMapping("/test")
|
||||
public R<String> test() {
|
||||
@@ -1377,4 +1391,889 @@ public class IotController extends BaseController {
|
||||
return R.fail("添加设备失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "设备校准")
|
||||
@PostMapping("/device/calibrate")
|
||||
public R<Void> setCalibrate(@RequestBody DeviceCalibrateBo request) {
|
||||
try {
|
||||
// 获取当前登录用户ID
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (userId == null) {
|
||||
return R.fail("未登录或登录已过期");
|
||||
}
|
||||
|
||||
// 验证校准码
|
||||
if (!"197346".equals(request.getCode())) {
|
||||
return R.fail("校准码错误");
|
||||
}
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getIotId, Device::getSerialNum,
|
||||
Device::getDeviceName, Device::getDeviceType, Device::getIsOxygenUsed,
|
||||
Device::getValueSaturability, Device::getWarnCode, Device::getDeadTime,
|
||||
Device::getValueDissolvedOxygen, Device::getValueTemperature)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)) {
|
||||
return R.fail("设备不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 如果是控制器且未启用溶解氧功能
|
||||
if (device.getDeviceType() == 2 && (device.getIsOxygenUsed() == null || device.getIsOxygenUsed() == 0)) {
|
||||
return R.fail("未启用溶解氧探头");
|
||||
}
|
||||
|
||||
// 检查设备是否到期
|
||||
if (device.getDeadTime() != null && new Date().after(device.getDeadTime())) {
|
||||
return R.fail("设备已到期");
|
||||
}
|
||||
|
||||
// 查询设备状态
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
|
||||
Map<String, Object> deviceDetail = iotDeviceService.queryDeviceInfo(device.getIotId());
|
||||
if (deviceDetail != null && deviceDetail.get("data") != null) {
|
||||
try {
|
||||
Object detailData = deviceDetail.get("data");
|
||||
java.lang.reflect.Method getStatusMethod = detailData.getClass().getMethod("getStatus");
|
||||
Object statusObj = getStatusMethod.invoke(detailData);
|
||||
if (statusObj != null) {
|
||||
String statusStr = statusObj.toString();
|
||||
if ("OFFLINE".equalsIgnoreCase(statusStr) || "offline".equals(statusStr)) {
|
||||
return R.fail("设备离线或断电");
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.warn("获取设备状态失败: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 设置校准属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("correct", 1);
|
||||
String propertiesJson = cn.hutool.json.JSONUtil.toJsonStr(properties);
|
||||
|
||||
Map<String, Object> setResult = iotDeviceService.setDeviceProperty(device.getIotId(), propertiesJson);
|
||||
if (setResult == null || !Boolean.TRUE.equals(setResult.get("success"))) {
|
||||
return R.fail("校准失败,请重试");
|
||||
}
|
||||
|
||||
// 更新设备警告码:清除未校准标记
|
||||
int warnCode = device.getWarnCode() != null ? device.getWarnCode() : 0;
|
||||
if ((warnCode & 0x0001) != 0) {
|
||||
warnCode &= ~0x0001; // 清除未校准标记
|
||||
}
|
||||
|
||||
// 更新设备
|
||||
deviceMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getWarnCode, warnCode)
|
||||
);
|
||||
|
||||
// 创建校准记录
|
||||
if (deviceCorrectRecordMapper != null) {
|
||||
com.intc.fishery.domain.DeviceCorrectRecord correctRecord = new com.intc.fishery.domain.DeviceCorrectRecord();
|
||||
correctRecord.setDeviceId(device.getId());
|
||||
correctRecord.setUserId(userId);
|
||||
correctRecord.setSerialNum(device.getSerialNum());
|
||||
correctRecord.setDeviceType(device.getDeviceType());
|
||||
correctRecord.setValueDissolvedOxygen(device.getValueDissolvedOxygen());
|
||||
correctRecord.setValueTemperature(device.getValueTemperature());
|
||||
correctRecord.setValueSaturability(device.getValueSaturability());
|
||||
deviceCorrectRecordMapper.insert(correctRecord);
|
||||
}
|
||||
|
||||
log.info("设备校准成功: userId={}, deviceId={}, deviceName={}, serialNum={}",
|
||||
userId, device.getId(), device.getDeviceName(), device.getSerialNum());
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("设备校准失败: {}", e.getMessage(), e);
|
||||
return R.fail("设备校准失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "设置盐度补偿")
|
||||
@PostMapping("/device/salinity-compensation")
|
||||
public R<Void> setSalinityCompensation(@RequestBody DeviceSalinityCompensationBo request) {
|
||||
try {
|
||||
// 获取当前登录用户ID
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (userId == null) {
|
||||
return R.fail("未登录或登录已过期");
|
||||
}
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getUserId, Device::getIotId, Device::getSerialNum,
|
||||
Device::getDeviceName, Device::getDeviceType, Device::getIsOxygenUsed,
|
||||
Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)) {
|
||||
return R.fail("设备不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 如果是控制器且未启用溶解氧功能
|
||||
if (device.getDeviceType() == 2 && (device.getIsOxygenUsed() == null || device.getIsOxygenUsed() == 0)) {
|
||||
return R.fail("未启用溶解氧探头");
|
||||
}
|
||||
|
||||
// 检查设备是否到期
|
||||
if (device.getDeadTime() != null && new Date().after(device.getDeadTime())) {
|
||||
return R.fail("设备已到期");
|
||||
}
|
||||
|
||||
// 查询设备状态
|
||||
if (iotDeviceService == null) {
|
||||
return R.fail("飞燕平台配置未启用");
|
||||
}
|
||||
|
||||
Map<String, Object> deviceDetail = iotDeviceService.queryDeviceInfo(device.getIotId());
|
||||
if (deviceDetail != null && deviceDetail.get("data") != null) {
|
||||
try {
|
||||
Object detailData = deviceDetail.get("data");
|
||||
java.lang.reflect.Method getStatusMethod = detailData.getClass().getMethod("getStatus");
|
||||
Object statusObj = getStatusMethod.invoke(detailData);
|
||||
if (statusObj != null) {
|
||||
String statusStr = statusObj.toString();
|
||||
if ("OFFLINE".equalsIgnoreCase(statusStr) || "offline".equals(statusStr)) {
|
||||
return R.fail("设备离线或断电");
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.warn("获取设备状态失败: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 设置盐度补偿属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("salinitySet", request.getSalinityCompensation());
|
||||
String propertiesJson = cn.hutool.json.JSONUtil.toJsonStr(properties);
|
||||
|
||||
Map<String, Object> setResult = iotDeviceService.setDeviceProperty(device.getIotId(), propertiesJson);
|
||||
if (setResult == null || !Boolean.TRUE.equals(setResult.get("success"))) {
|
||||
return R.fail("设置盐度补偿失败,请重试");
|
||||
}
|
||||
|
||||
// 更新设备盐度补偿值
|
||||
deviceMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getSalinityCompensation, request.getSalinityCompensation())
|
||||
);
|
||||
|
||||
log.info("设置盐度补偿成功: userId={}, deviceId={}, deviceName={}, serialNum={}, salinityCompensation={}‰",
|
||||
userId, device.getId(), device.getDeviceName(), device.getSerialNum(), request.getSalinityCompensation());
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("设置盐度补償失败: {}", e.getMessage(), e);
|
||||
return R.fail("设置盐度补償失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改设备输入电压类型
|
||||
*
|
||||
* @param request 请求对象(包含设备ID和电压类型)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "修改设备输入电压类型")
|
||||
@PutMapping("/device/voltage_type")
|
||||
public R<Void> updateDeviceVoltageType(
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "设置电压类型请求对象")
|
||||
@org.springframework.web.bind.annotation.RequestBody
|
||||
@jakarta.validation.Valid DeviceVoltageTypeBo request) {
|
||||
|
||||
try {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
log.info("修改设备输入电压类型请求: userId={}, deviceId={}, voltageType={}",
|
||||
userId, request.getId(), request.getVoltageType());
|
||||
|
||||
// 查询设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.select(Device::getId, Device::getIotId, Device::getUserId,
|
||||
Device::getSerialNum, Device::getDeviceName, Device::getDeviceType,
|
||||
Device::getInputVoltage, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
// 验证设备存在性、权限和设备类型(必须是测控一体机)
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)
|
||||
|| device.getDeviceType() == null || device.getDeviceType() != 2) {
|
||||
log.warn("设备不存在或无权限操作: userId={}, deviceId={}", userId, request.getId());
|
||||
return R.fail("设备不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 检查设备是否过期
|
||||
if (device.getDeadTime() != null && device.getDeadTime().before(new Date())) {
|
||||
log.warn("设备服务已过期: deviceId={}, deadTime={}", device.getId(), device.getDeadTime());
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 检查电压类型是否需要更新
|
||||
if (device.getInputVoltage() != null && device.getInputVoltage().equals(request.getVoltageType())) {
|
||||
log.info("电压类型未变化,无需更新: deviceId={}, voltageType={}",
|
||||
device.getId(), request.getVoltageType());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 检查设备是否在线(warnCode判断)
|
||||
if (device.getWarnCode() == null || device.getWarnCode() < 0) {
|
||||
log.warn("设备离线或已关机: deviceId={}, warnCode={}", device.getId(), device.getWarnCode());
|
||||
return R.fail("设备离线或已关机");
|
||||
}
|
||||
|
||||
// 构建IoT属性字典
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
|
||||
// 获取电压属性值
|
||||
Map<String, Object> voltData = ControllerHelper.getInputVoltageProperty(request.getVoltageType());
|
||||
if (voltData == null) {
|
||||
log.warn("电压参数错误: voltageType={}", request.getVoltageType());
|
||||
return R.fail("电压参数错误");
|
||||
}
|
||||
properties.put("rated_voltage", voltData);
|
||||
|
||||
// 如果是380V四相,需要设置每个开关的电压为380
|
||||
if (request.getVoltageType() == 4) {
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
String propertyKey = "Switch" + i + "_volt";
|
||||
properties.put(propertyKey, 380);
|
||||
}
|
||||
}
|
||||
|
||||
// 调用IoT云服务设置属性
|
||||
boolean result = iotCloudService.setProperty(device.getIotId(), properties, true, 2);
|
||||
if (!result) {
|
||||
log.error("设置IoT属性失败: deviceId=}, iotId={}", device.getId(), device.getIotId());
|
||||
return R.fail("设置电压失败");
|
||||
}
|
||||
|
||||
// 更新设备的输入电压类型
|
||||
deviceMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, request.getId())
|
||||
.set(Device::getInputVoltage, request.getVoltageType())
|
||||
);
|
||||
|
||||
// 更新关联开关的接线方式
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getDeviceId, request.getId())
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getConnectVoltageType, request.getVoltageType())
|
||||
);
|
||||
|
||||
String voltageDesc = ControllerHelper.getVoltageDescription(request.getVoltageType());
|
||||
log.info("修改设备输入电压类型成功: userId={}, deviceId={}, deviceName={}, serialNum={}, voltageType={}",
|
||||
userId, device.getId(), device.getDeviceName(), device.getSerialNum(), voltageDesc);
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("修改设备输入电压类型失败: {}", e.getMessage(), e);
|
||||
return R.fail("设置电压失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开关开启/关闭控制
|
||||
*
|
||||
* @param request 开关控制请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "开关开启/关闭控制")
|
||||
@PutMapping("/switch/turn_switch")
|
||||
public R<Void> turnSwitch(@RequestBody com.intc.fishery.domain.bo.ReqTurnOpen request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
}
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
Long switchId = request.getId();
|
||||
Integer targetStatus = request.getIsOpen();
|
||||
|
||||
// 查询开关信息
|
||||
com.intc.fishery.domain.DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
|
||||
// 查询关联的设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, deviceSwitch.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getIotId, Device::getSerialNum,
|
||||
Device::getDeviceName, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)) {
|
||||
return R.fail("开关不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 检查设备是否到期
|
||||
if (device.getDeadTime() != null && new Date().after(device.getDeadTime())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 防抖处理:检查距离上次操作是否小于3秒
|
||||
if (deviceSwitch.getLastTurnTime() != null) {
|
||||
long timeDiff = System.currentTimeMillis() - deviceSwitch.getLastTurnTime().getTime();
|
||||
if (timeDiff < 3000) {
|
||||
return R.fail("操作过于频繁,请稍后再试");
|
||||
}
|
||||
}
|
||||
|
||||
// 如果开关状态已经是目标状态,无需操作
|
||||
if (deviceSwitch.getIsOpen() != null && deviceSwitch.getIsOpen().equals(targetStatus)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 检查设备是否离线(warnCode为99表示离线)
|
||||
if (device.getWarnCode() == null || device.getWarnCode() == 99) {
|
||||
return R.fail("设备离线或已关机");
|
||||
}
|
||||
|
||||
// 检查IoT云服务是否可用
|
||||
if (iotCloudService == null) {
|
||||
return R.fail("物联网服务未启用");
|
||||
}
|
||||
|
||||
// 构造IoT属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("switchIndex" + deviceSwitch.getIndex(), targetStatus);
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(device.getIotId(), properties, true, 2);
|
||||
if (!success) {
|
||||
return R.fail("设置开关失败");
|
||||
}
|
||||
|
||||
// 更新数据库中的开关状态和最后操作时间
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLastTurnTime, new Date())
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
String operation = targetStatus == 1 ? "开启" : "关闭";
|
||||
log.info("开关操作:{}({})的开关{}:{}",
|
||||
device.getDeviceName(), device.getSerialNum(), deviceSwitch.getSwitchName(), operation);
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("开关控制失败: {}", e.getMessage(), e);
|
||||
return R.fail("开关控制失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置塘口所有开关状态
|
||||
*
|
||||
* @param request 开关状态请求对象(id为塘口ID)
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "设置塘口所有开关状态")
|
||||
@PutMapping("/switch/turn_pond_switch")
|
||||
public R<Void> turnPondSwitch(@RequestBody com.intc.fishery.domain.bo.ReqTurnOpen request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
}
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
Long pondId = request.getId();
|
||||
Integer targetStatus = request.getIsOpen();
|
||||
|
||||
// 查询塘口下所有开关信息(包括关联的设备信息)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
.selectAs(Device::getUserId, "userId")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(Device::getDeadTime, "deadTime")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getPondId, pondId);
|
||||
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> listSwitch =
|
||||
deviceSwitchMapper.selectJoinList(com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (listSwitch == null || listSwitch.isEmpty()) {
|
||||
return R.fail("该塘口下没有开关");
|
||||
}
|
||||
|
||||
// 按设备IotId分组,并过滤不符合条件的开关
|
||||
Map<String, java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo>> iotIdSwitchMap =
|
||||
new java.util.HashMap<>();
|
||||
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : listSwitch) {
|
||||
// 权限验证
|
||||
if (switchVo.getUserId() == null || !switchVo.getUserId().equals(userId)) {
|
||||
return R.fail("开关不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 如果状态已经是目标状态,跳过
|
||||
if (switchVo.getIsOpen() != null && switchVo.getIsOpen().equals(targetStatus)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果设备已到期,跳过
|
||||
if (switchVo.getDeadTime() != null && new Date().after(switchVo.getDeadTime())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果设备离线,跳过
|
||||
if (switchVo.getWarnCode() == null || switchVo.getWarnCode() == 99) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 防抖处理:检查距离上次操作是否小于1秒
|
||||
if (switchVo.getLastTurnTime() != null) {
|
||||
long timeDiff = System.currentTimeMillis() - switchVo.getLastTurnTime().getTime();
|
||||
if (timeDiff < 1000) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 按IotId分组
|
||||
String iotId = switchVo.getIotId();
|
||||
if (com.intc.common.core.utils.StringUtils.isBlank(iotId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
iotIdSwitchMap.computeIfAbsent(iotId, k -> new java.util.ArrayList<>()).add(switchVo);
|
||||
}
|
||||
|
||||
// 检查IoT云服务是否可用
|
||||
if (iotCloudService == null) {
|
||||
return R.fail("物联网服务未启用");
|
||||
}
|
||||
|
||||
// 按设备批量设置开关状态
|
||||
java.util.Set<Long> successSwitchIds = new java.util.HashSet<>();
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> successSwitches = new java.util.ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo>> entry : iotIdSwitchMap.entrySet()) {
|
||||
String iotId = entry.getKey();
|
||||
java.util.List<com.intc.fishery.domain.vo.DeviceSwitchVo> switches = entry.getValue();
|
||||
|
||||
// 构造该设备的所有开关属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : switches) {
|
||||
properties.put("switchIndex" + switchVo.getIndex(), targetStatus);
|
||||
}
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(iotId, properties, false, 0);
|
||||
if (success) {
|
||||
// 记录成功的开关ID
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : switches) {
|
||||
successSwitchIds.add(switchVo.getId());
|
||||
successSwitches.add(switchVo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 批量更新数据库中成功设置的开关状态
|
||||
if (!successSwitchIds.isEmpty()) {
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.in(com.intc.fishery.domain.DeviceSwitch::getId, successSwitchIds)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, targetStatus)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLastTurnTime, new Date())
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
String operation = targetStatus == 1 ? "开启" : "关闭";
|
||||
for (com.intc.fishery.domain.vo.DeviceSwitchVo switchVo : successSwitches) {
|
||||
log.info("开关操作:{}({})的开关{}:{}",
|
||||
switchVo.getDeviceName(), switchVo.getSerialNum(), switchVo.getSwitchName(), operation);
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("设置塘口开关失败: {}", e.getMessage(), e);
|
||||
return R.fail("设置塘口开关失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开关额定电流
|
||||
*
|
||||
* @param request 设置额定电流请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "设置开关额定电流")
|
||||
@PutMapping("/switch/electric_set")
|
||||
public R<Void> updateElectricSet(@RequestBody com.intc.fishery.domain.bo.ReqSwitchElectricSet request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
}
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
Long switchId = request.getId();
|
||||
Double electric = request.getElectric();
|
||||
|
||||
// 查询开关信息
|
||||
com.intc.fishery.domain.DeviceSwitch deviceSwitch = deviceSwitchMapper.selectById(switchId);
|
||||
if (deviceSwitch == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
|
||||
// 查询关联的设备信息
|
||||
Device device = deviceMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||
.eq(Device::getId, deviceSwitch.getDeviceId())
|
||||
.select(Device::getId, Device::getUserId, Device::getIotId, Device::getSerialNum,
|
||||
Device::getDeviceName, Device::getWarnCode, Device::getDeadTime)
|
||||
);
|
||||
|
||||
// 权限验证
|
||||
if (device == null || device.getUserId() == null || !device.getUserId().equals(userId)) {
|
||||
return R.fail("开关不存在或无权限访问");
|
||||
}
|
||||
|
||||
// 检查设备是否到期
|
||||
if (device.getDeadTime() != null && new Date().after(device.getDeadTime())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 检查额定电流值是否已改变(精度0.001)
|
||||
if (deviceSwitch.getRateElectricValue() != null
|
||||
&& Math.abs(deviceSwitch.getRateElectricValue() - electric) < 0.001) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 检查设备是否离线(warnCode为99表示离线)
|
||||
if (device.getWarnCode() == null || device.getWarnCode() == 99) {
|
||||
return R.fail("设备离线或已关机");
|
||||
}
|
||||
|
||||
// 检查IoT云服务是否可用
|
||||
if (iotCloudService == null) {
|
||||
return R.fail("物联网服务未启用");
|
||||
}
|
||||
|
||||
// 构造IoT属性:rating_switch{Index}
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put("rating_switch" + deviceSwitch.getIndex(), electric);
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(device.getIotId(), properties, true, 2);
|
||||
if (!success) {
|
||||
return R.fail("设置额定电流失败");
|
||||
}
|
||||
|
||||
// 更新数据库中的额定电流值
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getRateElectricValue, electric)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
log.info("开关操作:{}({})的开关{},额定电流设置:{:00}A",
|
||||
device.getDeviceName(), device.getSerialNum(), deviceSwitch.getSwitchName(), electric);
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("设置额定电流失败: {}", e.getMessage(), e);
|
||||
return R.fail("设置额定电流失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改开关输出电压类型
|
||||
*
|
||||
* @param request 电压类型请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "修改开关输出电压类型")
|
||||
@PutMapping("/switch/update_voltage_type")
|
||||
public R<Void> updateConnectVoltageType(@RequestBody com.intc.fishery.domain.bo.ReqSetVoltageType request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
}
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
Long switchId = request.getId();
|
||||
Integer voltageType = request.getVoltageType();
|
||||
|
||||
// 查询开关信息(包括关联的设备信息)
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
.selectAs(Device::getUserId, "userId")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getDeviceType, "deviceType")
|
||||
.selectAs(Device::getInputVoltage, "inputVoltage")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(Device::getDeadTime, "deadTime")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId);
|
||||
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo switchVo =
|
||||
deviceSwitchMapper.selectJoinOne(com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (switchVo == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
|
||||
// 权限验证:检查设备类型为控制器(deviceType=2)且属于当前用户
|
||||
if (switchVo.getUserId() == null || !switchVo.getUserId().equals(userId)) {
|
||||
return R.fail("开关不存在或无权限访问");
|
||||
}
|
||||
|
||||
if (switchVo.getDeviceType() == null || switchVo.getDeviceType() != 2) {
|
||||
return R.fail("仅测控一体机支持该操作");
|
||||
}
|
||||
|
||||
// 检查设备是否到期
|
||||
if (switchVo.getDeadTime() != null && new Date().after(switchVo.getDeadTime())) {
|
||||
return R.fail("设备服务已过期");
|
||||
}
|
||||
|
||||
// 检查电压类型是否已改变
|
||||
if (switchVo.getConnectVoltageType() != null && switchVo.getConnectVoltageType().equals(voltageType)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 检查设备是否离线
|
||||
if (switchVo.getWarnCode() == null || switchVo.getWarnCode() == 99) {
|
||||
return R.fail("设备离线或已关机");
|
||||
}
|
||||
|
||||
// 检查设备输入电压是否支持设置(必须是三相380V四线,inputVoltage >= 4)
|
||||
if (switchVo.getInputVoltage() == null || switchVo.getInputVoltage() < 4) {
|
||||
return R.fail("不可设置");
|
||||
}
|
||||
|
||||
// 检查目标电压类型是否合法(1-单相220V,4-三相380V四线)
|
||||
if (voltageType != 1 && voltageType != 4) {
|
||||
return R.fail("不可设置");
|
||||
}
|
||||
|
||||
// 检查IoT云服务是否可用
|
||||
if (iotCloudService == null) {
|
||||
return R.fail("物联网服务未启用");
|
||||
}
|
||||
|
||||
// 构造IoT属性:Switch{Index}_volt
|
||||
String propertyKey = "Switch" + switchVo.getIndex() + "_volt";
|
||||
int voltage = voltageType == 1 ? 220 : 380;
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
properties.put(propertyKey, voltage);
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(switchVo.getIotId(), properties, true, 2);
|
||||
if (!success) {
|
||||
return R.fail("设置电压失败");
|
||||
}
|
||||
|
||||
// 更新数据库中的电压类型
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getConnectVoltageType, voltageType)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
String voltageMsg = getVoltageTypeDesc(voltageType);
|
||||
log.info("开关操作:{}({})的开关{},修改输出电压接线方式为{}",
|
||||
switchVo.getDeviceName(), switchVo.getSerialNum(), switchVo.getSwitchName(), voltageMsg);
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("修改电压类型失败: {}", e.getMessage(), e);
|
||||
return R.fail("修改电压类型失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电压类型描述
|
||||
*
|
||||
* @param voltageType 电压类型
|
||||
* @return 电压类型描述
|
||||
*/
|
||||
private String getVoltageTypeDesc(Integer voltageType) {
|
||||
if (voltageType == null) {
|
||||
return "未知";
|
||||
}
|
||||
switch (voltageType) {
|
||||
case 1:
|
||||
return "单相220V";
|
||||
case 2:
|
||||
return "单相220V三线";
|
||||
case 3:
|
||||
return "三相380V三线";
|
||||
case 4:
|
||||
return "三相380V四线";
|
||||
default:
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改开关所属塘口
|
||||
*
|
||||
* @param request 修改塘口请求对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Operation(summary = "修改开关所属塘口")
|
||||
@PutMapping("/switch/update_pond")
|
||||
public R<Void> updateSwitchPond(@RequestBody com.intc.fishery.domain.bo.ReqChangePond request) {
|
||||
try {
|
||||
if (deviceSwitchMapper == null || pondMapper == null || deviceMapper == null) {
|
||||
return R.fail("系统配置未完成");
|
||||
}
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
Long switchId = request.getId();
|
||||
Long pondId = request.getPondId();
|
||||
|
||||
// 查询开关信息,包括关联的设备和塘口信息
|
||||
com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch> wrapper =
|
||||
new com.github.yulichang.wrapper.MPJLambdaWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.selectAll(com.intc.fishery.domain.DeviceSwitch.class)
|
||||
.selectAs(Device::getDeviceName, "deviceName")
|
||||
.selectAs(Device::getSerialNum, "serialNum")
|
||||
.selectAs(Device::getIotId, "iotId")
|
||||
.selectAs(Device::getWarnCode, "warnCode")
|
||||
.selectAs(com.intc.fishery.domain.Pond::getPondName, "pondName")
|
||||
.leftJoin(Device.class, Device::getId, com.intc.fishery.domain.DeviceSwitch::getDeviceId)
|
||||
.leftJoin(com.intc.fishery.domain.Pond.class, com.intc.fishery.domain.Pond::getId, com.intc.fishery.domain.DeviceSwitch::getPondId)
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId);
|
||||
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo vo = deviceSwitchMapper.selectJoinOne(
|
||||
com.intc.fishery.domain.vo.DeviceSwitchVo.class, wrapper);
|
||||
|
||||
if (vo == null) {
|
||||
return R.fail("开关不存在");
|
||||
}
|
||||
|
||||
Long oldPondId = vo.getPondId();
|
||||
String oldPondName = vo.getPondName();
|
||||
|
||||
// 如果已有塘口且与新塘口相同,无需处理
|
||||
if (oldPondId != null && oldPondId.equals(pondId)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 如果开关原本有塘口,需要清理定时控制
|
||||
if (oldPondId != null) {
|
||||
// 查询设备的IotId
|
||||
Device device = deviceMapper.selectById(vo.getDeviceId());
|
||||
if (device != null && com.intc.common.core.utils.StringUtils.isNotBlank(device.getIotId())) {
|
||||
// 检查设备是否在线(通过判断warnCode判断设备状态)
|
||||
boolean isOnline = device.getWarnCode() != null && device.getWarnCode() != 99;
|
||||
|
||||
if (isOnline && iotCloudService != null) {
|
||||
try {
|
||||
// 构造清空定时控制的属性
|
||||
Map<String, Object> properties = new java.util.HashMap<>();
|
||||
// 清空定时器:localTimer_switch{Index}
|
||||
properties.put("localTimer_switch" + vo.getIndex(), java.util.Collections.emptyList());
|
||||
|
||||
// 如果开关是打开状态,需要关闭它
|
||||
if (vo.getIsOpen() != null && vo.getIsOpen() == 1) {
|
||||
// 关闭开关:switchIndex{Index} = 0
|
||||
properties.put("switchIndex" + vo.getIndex(), 0);
|
||||
|
||||
// 更新数据库中的开关状态
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getIsOpen, 0)
|
||||
);
|
||||
}
|
||||
|
||||
// 调用物联网服务设置属性
|
||||
boolean success = iotCloudService.setProperty(device.getIotId(), properties, false, 0);
|
||||
|
||||
if (success) {
|
||||
log.info("成功通过物联网服务清空开关定时控制和关闭开关, switchId={}", switchId);
|
||||
} else {
|
||||
log.warn("通过物联网服务清空开关定时控制失败, switchId={}", switchId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("调用物联网服务失败, switchId={}", switchId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除该开关的所有定时控制记录
|
||||
if (timingCtrlMapper != null) {
|
||||
timingCtrlMapper.delete(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.intc.fishery.domain.TimingCtrl>()
|
||||
.eq(com.intc.fishery.domain.TimingCtrl::getSwitchId, switchId)
|
||||
);
|
||||
}
|
||||
|
||||
log.info("已清除开关ID={}的定时控制数据", switchId);
|
||||
}
|
||||
|
||||
// 处理新塘口分配
|
||||
if (pondId != null && pondId > 0) {
|
||||
// 验证塘口是否存在
|
||||
com.intc.fishery.domain.Pond pond = pondMapper.selectById(pondId);
|
||||
if (pond == null) {
|
||||
return R.fail("塘口不存在");
|
||||
}
|
||||
|
||||
// 更新开关的塘口ID,并清空联动控制ID
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getPondId, pondId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLinkedCtrlId, null)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
if (oldPondId != null) {
|
||||
log.info("开关操作:{}({})的开关{},转移到塘口:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), pond.getPondName());
|
||||
} else {
|
||||
log.info("开关操作:{}({})的开关{},分配到塘口:{}",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), pond.getPondName());
|
||||
}
|
||||
} else if (oldPondId != null) {
|
||||
// 移除塘口分配
|
||||
deviceSwitchMapper.update(null,
|
||||
new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<com.intc.fishery.domain.DeviceSwitch>()
|
||||
.eq(com.intc.fishery.domain.DeviceSwitch::getId, switchId)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getPondId, null)
|
||||
.set(com.intc.fishery.domain.DeviceSwitch::getLinkedCtrlId, null)
|
||||
);
|
||||
|
||||
// 记录操作日志
|
||||
log.info("开关操作:{}({})的开关{} 从 {} 移除",
|
||||
vo.getDeviceName(), vo.getSerialNum(), vo.getSwitchName(), oldPondName);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
log.error("修改开关塘口失败: {}", e.getMessage(), e);
|
||||
return R.fail("修改失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.intc.iot.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备校准请求业务对象
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "设备校准请求对象")
|
||||
public class DeviceCalibrateBo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 校准码
|
||||
*/
|
||||
@Schema(description = "校准码")
|
||||
@NotBlank(message = "校准码不能为空")
|
||||
private String code;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.intc.iot.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设备盐度补偿请求业务对象
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "设备盐度补偿请求对象")
|
||||
public class DeviceSalinityCompensationBo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 盐度补偿值
|
||||
*/
|
||||
@Schema(description = "盐度补偿值")
|
||||
@NotNull(message = "盐度补偿值不能为空")
|
||||
private Double salinityCompensation;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.intc.iot.domain.bo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 设置设备输入电压类型请求对象
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "设置设备输入电压类型请求对象")
|
||||
public class DeviceVoltageTypeBo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
@Schema(description = "设备ID")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 电压类型(1-220V单相,2-220V两相,3-380V三相,4-380V四相)
|
||||
*/
|
||||
@Schema(description = "电压类型(1-220V单相,2-220V两相,3-380V三相,4-380V四相)")
|
||||
@NotNull(message = "电压类型不能为空")
|
||||
private Integer voltageType;
|
||||
}
|
||||
@@ -88,4 +88,23 @@ public interface IotDeviceService {
|
||||
*/
|
||||
Map<String, Object> queryThingModel(String productKey) throws Exception;
|
||||
|
||||
/**
|
||||
* 设置设备校准
|
||||
*
|
||||
* @param iotId 设备ID
|
||||
* @return 是否成功
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
boolean calibrateDevice(String iotId) throws Exception;
|
||||
|
||||
/**
|
||||
* 设置设备盐度补偿
|
||||
*
|
||||
* @param iotId 设备ID
|
||||
* @param salinityCompensation 盐度补偿值
|
||||
* @return 是否成功
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
boolean setSalinityCompensation(String iotId, Double salinityCompensation) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -191,4 +191,44 @@ public class IotDeviceServiceImpl implements IotDeviceService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean calibrateDevice(String iotId) throws Exception {
|
||||
log.info("设置设备校准,IotId: {}", iotId);
|
||||
|
||||
// 构造属性JSON:{"correct": 1}
|
||||
String properties = "{\"correct\": 1}";
|
||||
|
||||
SetDevicePropertyRequest request = new SetDevicePropertyRequest();
|
||||
request.setIotId(iotId);
|
||||
request.setItems(properties);
|
||||
|
||||
SetDevicePropertyResponse response = acsClient.getAcsResponse(request);
|
||||
|
||||
if (!response.getSuccess()) {
|
||||
log.error("设置设备校准失败,Code: {}, ErrorMessage: {}", response.getCode(), response.getErrorMessage());
|
||||
}
|
||||
|
||||
return response.getSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSalinityCompensation(String iotId, Double salinityCompensation) throws Exception {
|
||||
log.info("设置设备盐度补偿,IotId: {}, SalinityCompensation: {}", iotId, salinityCompensation);
|
||||
|
||||
// 构造属性JSON:{"salinitySet": value}
|
||||
String properties = String.format("{\"salinitySet\": %s}", salinityCompensation);
|
||||
|
||||
SetDevicePropertyRequest request = new SetDevicePropertyRequest();
|
||||
request.setIotId(iotId);
|
||||
request.setItems(properties);
|
||||
|
||||
SetDevicePropertyResponse response = acsClient.getAcsResponse(request);
|
||||
|
||||
if (!response.getSuccess()) {
|
||||
log.error("设置设备盐度补偿失败,Code: {}, ErrorMessage: {}", response.getCode(), response.getErrorMessage());
|
||||
}
|
||||
|
||||
return response.getSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.intc.iot.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备控制辅助工具类
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
public class ControllerHelper {
|
||||
|
||||
/**
|
||||
* 获取输入电压属性值
|
||||
* 根据电压类型返回对应的IoT平台属性值
|
||||
* 注意:rated_voltage是结构体类型,尝试只使用phase字段
|
||||
*
|
||||
* @param voltageType 电压类型(1-220V单相,2-220V两相,3-380V三相,4-380V四相)
|
||||
* @return IoT平台属性值的Map
|
||||
*/
|
||||
public static Map<String, Object> getInputVoltageProperty(Integer voltageType) {
|
||||
if (voltageType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 尝试只设置phase字段
|
||||
switch (voltageType) {
|
||||
case 1: // 220V单相
|
||||
result.put("phase", "1");
|
||||
break;
|
||||
case 2: // 220V两相
|
||||
result.put("phase", "2");
|
||||
break;
|
||||
case 3: // 380V三相
|
||||
result.put("phase", "3");
|
||||
break;
|
||||
case 4: // 380V四相
|
||||
result.put("phase", "4");
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电压类型的中文描述
|
||||
*
|
||||
* @param voltageType 电压类型
|
||||
* @return 中文描述
|
||||
*/
|
||||
public static String getVoltageDescription(Integer voltageType) {
|
||||
if (voltageType == null) {
|
||||
return "未知";
|
||||
}
|
||||
|
||||
switch (voltageType) {
|
||||
case 1:
|
||||
return "220V单相";
|
||||
case 2:
|
||||
return "220V两相";
|
||||
case 3:
|
||||
return "380V三相";
|
||||
case 4:
|
||||
return "380V四相";
|
||||
default:
|
||||
return "未知类型";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class SysNoticeController extends BaseController {
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
*/
|
||||
@SaCheckPermission("system:notice:list")
|
||||
// @SaCheckPermission("system:notice:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<SysNoticeVo> list(SysNoticeBo notice, PageQuery pageQuery) {
|
||||
return noticeService.selectPageNoticeList(notice, pageQuery);
|
||||
|
||||
Reference in New Issue
Block a user