fix: 设备解绑后,新生成一个无用户无塘口的设备信息。
This commit is contained in:
@@ -9,6 +9,7 @@ import com.intc.common.core.utils.MapstructUtils;
|
|||||||
import com.intc.common.core.utils.StringUtils;
|
import com.intc.common.core.utils.StringUtils;
|
||||||
import com.intc.common.mybatis.core.page.PageQuery;
|
import com.intc.common.mybatis.core.page.PageQuery;
|
||||||
import com.intc.common.mybatis.core.page.TableDataInfo;
|
import com.intc.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import com.intc.common.redis.utils.RedisUtils;
|
||||||
import com.intc.fishery.domain.AquUser;
|
import com.intc.fishery.domain.AquUser;
|
||||||
import com.intc.fishery.domain.Device;
|
import com.intc.fishery.domain.Device;
|
||||||
import com.intc.fishery.domain.DeviceBindRecord;
|
import com.intc.fishery.domain.DeviceBindRecord;
|
||||||
@@ -20,6 +21,8 @@ import com.intc.fishery.domain.Pond;
|
|||||||
import com.intc.fishery.domain.TimingCtrl;
|
import com.intc.fishery.domain.TimingCtrl;
|
||||||
import com.intc.fishery.domain.bo.DeviceBo;
|
import com.intc.fishery.domain.bo.DeviceBo;
|
||||||
import com.intc.fishery.domain.vo.DeviceVo;
|
import com.intc.fishery.domain.vo.DeviceVo;
|
||||||
|
import com.intc.fishery.constant.DefineDeviceWarnCode;
|
||||||
|
import com.intc.fishery.mapper.AquUserMapper;
|
||||||
import com.intc.fishery.mapper.DeviceBindRecordMapper;
|
import com.intc.fishery.mapper.DeviceBindRecordMapper;
|
||||||
import com.intc.fishery.mapper.DeviceCorrectRecordMapper;
|
import com.intc.fishery.mapper.DeviceCorrectRecordMapper;
|
||||||
import com.intc.fishery.mapper.DeviceErrorCodeMapper;
|
import com.intc.fishery.mapper.DeviceErrorCodeMapper;
|
||||||
@@ -28,6 +31,7 @@ import com.intc.fishery.mapper.DeviceSwitchMapper;
|
|||||||
import com.intc.fishery.mapper.LinkedCtrlMapper;
|
import com.intc.fishery.mapper.LinkedCtrlMapper;
|
||||||
import com.intc.fishery.mapper.TimingCtrlMapper;
|
import com.intc.fishery.mapper.TimingCtrlMapper;
|
||||||
import com.intc.fishery.service.IDeviceService;
|
import com.intc.fishery.service.IDeviceService;
|
||||||
|
import com.intc.fishery.utils.MessageOpRecordUtil;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -49,6 +53,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
public class DeviceServiceImpl implements IDeviceService {
|
public class DeviceServiceImpl implements IDeviceService {
|
||||||
|
|
||||||
private final DeviceMapper baseMapper;
|
private final DeviceMapper baseMapper;
|
||||||
|
private final AquUserMapper aquUserMapper;
|
||||||
private final DeviceBindRecordMapper deviceBindRecordMapper;
|
private final DeviceBindRecordMapper deviceBindRecordMapper;
|
||||||
private final DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
private final DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||||
private final DeviceErrorCodeMapper deviceErrorCodeMapper;
|
private final DeviceErrorCodeMapper deviceErrorCodeMapper;
|
||||||
@@ -56,6 +61,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
private final LinkedCtrlMapper linkedCtrlMapper;
|
private final LinkedCtrlMapper linkedCtrlMapper;
|
||||||
private final TimingCtrlMapper timingCtrlMapper;
|
private final TimingCtrlMapper timingCtrlMapper;
|
||||||
|
|
||||||
|
/** Redis 离线等待标记前缀(与 DeviceDataHandler 保持一致) */
|
||||||
|
private static final String DEVICE_OFFLINE_WAIT_KEY_PREFIX = "device:offline:wait:";
|
||||||
|
/** Redis 溶解氧探头离线等待标记前缀 */
|
||||||
|
private static final String DETECTOR_OXY_OFFLINE_WAIT_KEY_PREFIX = "device:detector:oxy:offline:wait:";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询设备管理
|
* 查询设备管理
|
||||||
*
|
*
|
||||||
@@ -224,8 +234,18 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验并批量删除设备管理信息
|
* 校验并批量删除设备管理信息(参考 C# DeleteDevice 逻辑)
|
||||||
* 删除顺序:故障码 -> 校准记录 -> 定时控制 -> 开关(先解除联动控制引用) -> 联动控制 -> 设备
|
* <p>
|
||||||
|
* 处理流程:
|
||||||
|
* 1. 查询完整设备信息与用户信息
|
||||||
|
* 2. 新增解绑记录
|
||||||
|
* 3. 删除联动控制
|
||||||
|
* 4. 删除关联数据(故障码、校准记录、定时控制、开关)
|
||||||
|
* 5. 删除设备
|
||||||
|
* 6. 非管理员用户:创建新的无绑定设备(保留IoT信息)
|
||||||
|
* 7. 清除告警数据(warnCode + Redis离线等待标记)
|
||||||
|
* 8. 记录操作日志
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param ids 待删除的主键集合
|
* @param ids 待删除的主键集合
|
||||||
* @param isValid 是否进行有效性校验
|
* @param isValid 是否进行有效性校验
|
||||||
@@ -234,85 +254,23 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||||
if(isValid){
|
if (isValid) {
|
||||||
//TODO 做一些业务上的校验,判断是否需要校验
|
//TODO 做一些业务上的校验,判断是否需要校验
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 删除设备关联的故障码记录
|
// 1. 先查询完整设备信息(删除前需要用到各字段)
|
||||||
deviceErrorCodeMapper.delete(
|
|
||||||
new LambdaQueryWrapper<DeviceErrorCode>()
|
|
||||||
.in(DeviceErrorCode::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 2. 删除设备关联的校准记录
|
|
||||||
deviceCorrectRecordMapper.delete(
|
|
||||||
new LambdaQueryWrapper<DeviceCorrectRecord>()
|
|
||||||
.in(DeviceCorrectRecord::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 3. 查询设备关联的开关
|
|
||||||
List<DeviceSwitch> switches = deviceSwitchMapper.selectList(
|
|
||||||
new LambdaQueryWrapper<DeviceSwitch>()
|
|
||||||
.in(DeviceSwitch::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!switches.isEmpty()) {
|
|
||||||
// 收集开关ID
|
|
||||||
List<Long> switchIds = switches.stream()
|
|
||||||
.map(DeviceSwitch::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
// 4. 删除开关关联的定时控制
|
|
||||||
timingCtrlMapper.delete(
|
|
||||||
new LambdaQueryWrapper<TimingCtrl>()
|
|
||||||
.in(TimingCtrl::getSwitchId, switchIds)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 收集开关关联的联动控制ID
|
|
||||||
List<Long> linkedCtrlIds = switches.stream()
|
|
||||||
.map(DeviceSwitch::getLinkedCtrlId)
|
|
||||||
.filter(id -> id != null && id > 0)
|
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
// 5. 解除开关与联动控制的绑定
|
|
||||||
deviceSwitchMapper.update(null,
|
|
||||||
new LambdaUpdateWrapper<DeviceSwitch>()
|
|
||||||
.set(DeviceSwitch::getLinkedCtrlId, null)
|
|
||||||
.in(DeviceSwitch::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 6. 删除联动控制(如果有)
|
|
||||||
if (!linkedCtrlIds.isEmpty()) {
|
|
||||||
linkedCtrlMapper.delete(
|
|
||||||
new LambdaQueryWrapper<LinkedCtrl>()
|
|
||||||
.in(LinkedCtrl::getId, linkedCtrlIds)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 删除开关
|
|
||||||
deviceSwitchMapper.delete(
|
|
||||||
new LambdaQueryWrapper<DeviceSwitch>()
|
|
||||||
.in(DeviceSwitch::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 删除设备本身关联的联动控制
|
|
||||||
linkedCtrlMapper.delete(
|
|
||||||
new LambdaQueryWrapper<LinkedCtrl>()
|
|
||||||
.in(LinkedCtrl::getDeviceId, ids)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 9. 查询要删除的设备信息,添加解绑记录
|
|
||||||
List<Device> devicesToDelete = baseMapper.selectList(
|
List<Device> devicesToDelete = baseMapper.selectList(
|
||||||
new LambdaQueryWrapper<Device>()
|
new LambdaQueryWrapper<Device>()
|
||||||
.in(Device::getId, ids)
|
.in(Device::getId, ids)
|
||||||
.select(Device::getId, Device::getUserId, Device::getIotId,
|
|
||||||
Device::getDeviceType, Device::getSerialNum)
|
|
||||||
);
|
);
|
||||||
|
if (devicesToDelete.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 为每个设备添加解绑记录
|
|
||||||
for (Device device : devicesToDelete) {
|
for (Device device : devicesToDelete) {
|
||||||
|
Long deviceId = device.getId();
|
||||||
|
|
||||||
|
// 2. 新增解绑记录
|
||||||
try {
|
try {
|
||||||
DeviceBindRecord unbindRecord = new DeviceBindRecord();
|
DeviceBindRecord unbindRecord = new DeviceBindRecord();
|
||||||
unbindRecord.setUserId(device.getUserId());
|
unbindRecord.setUserId(device.getUserId());
|
||||||
@@ -322,15 +280,135 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
unbindRecord.setSerialNum(device.getSerialNum());
|
unbindRecord.setSerialNum(device.getSerialNum());
|
||||||
deviceBindRecordMapper.insert(unbindRecord);
|
deviceBindRecordMapper.insert(unbindRecord);
|
||||||
log.info("添加设备解绑记录: deviceId={}, userId={}, serialNum={}",
|
log.info("添加设备解绑记录: deviceId={}, userId={}, serialNum={}",
|
||||||
device.getId(), device.getUserId(), device.getSerialNum());
|
deviceId, device.getUserId(), device.getSerialNum());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("添加设备解绑记录失败: deviceId={}, error={}", device.getId(), e.getMessage(), e);
|
log.error("添加设备解绑记录失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
// 不影响删除流程,继续执行
|
}
|
||||||
|
|
||||||
|
// 3. 删除设备关联的联动控制
|
||||||
|
linkedCtrlMapper.delete(
|
||||||
|
new LambdaQueryWrapper<LinkedCtrl>()
|
||||||
|
.eq(LinkedCtrl::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4. 删除设备关联的故障码记录
|
||||||
|
deviceErrorCodeMapper.delete(
|
||||||
|
new LambdaQueryWrapper<DeviceErrorCode>()
|
||||||
|
.eq(DeviceErrorCode::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 5. 删除设备关联的校准记录
|
||||||
|
deviceCorrectRecordMapper.delete(
|
||||||
|
new LambdaQueryWrapper<DeviceCorrectRecord>()
|
||||||
|
.eq(DeviceCorrectRecord::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 6. 查询设备关联的开关,删除定时控制、解除联动绑定后删除开关
|
||||||
|
List<DeviceSwitch> switches = deviceSwitchMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<DeviceSwitch>()
|
||||||
|
.eq(DeviceSwitch::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
if (!switches.isEmpty()) {
|
||||||
|
List<Long> switchIds = switches.stream()
|
||||||
|
.map(DeviceSwitch::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 删除开关关联的定时控制
|
||||||
|
timingCtrlMapper.delete(
|
||||||
|
new LambdaQueryWrapper<TimingCtrl>()
|
||||||
|
.in(TimingCtrl::getSwitchId, switchIds)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 收集开关关联的联动控制ID
|
||||||
|
List<Long> linkedCtrlIds = switches.stream()
|
||||||
|
.map(DeviceSwitch::getLinkedCtrlId)
|
||||||
|
.filter(id -> id != null && id > 0)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 解除开关与联动控制的绑定
|
||||||
|
deviceSwitchMapper.update(null,
|
||||||
|
new LambdaUpdateWrapper<DeviceSwitch>()
|
||||||
|
.set(DeviceSwitch::getLinkedCtrlId, null)
|
||||||
|
.eq(DeviceSwitch::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 删除联动控制(如果有)
|
||||||
|
if (!linkedCtrlIds.isEmpty()) {
|
||||||
|
linkedCtrlMapper.delete(
|
||||||
|
new LambdaQueryWrapper<LinkedCtrl>()
|
||||||
|
.in(LinkedCtrl::getId, linkedCtrlIds)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除开关
|
||||||
|
deviceSwitchMapper.delete(
|
||||||
|
new LambdaQueryWrapper<DeviceSwitch>()
|
||||||
|
.eq(DeviceSwitch::getDeviceId, deviceId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 删除设备记录
|
||||||
|
baseMapper.deleteById(deviceId);
|
||||||
|
|
||||||
|
// 8. 用户:创建新的无绑定设备(保留IoT信息,清除用户和塘口关联)
|
||||||
|
if (device.getUserId() != null) {
|
||||||
|
try {
|
||||||
|
AquUser user = aquUserMapper.selectById(device.getUserId());
|
||||||
|
if (user != null) {
|
||||||
|
Device newDevice = new Device();
|
||||||
|
newDevice.setUserId(null);
|
||||||
|
newDevice.setIsOxygenUsed(device.getIsOxygenUsed());
|
||||||
|
newDevice.setIotId(device.getIotId());
|
||||||
|
newDevice.setSerialNum(device.getSerialNum());
|
||||||
|
newDevice.setDeviceName(device.getDeviceName());
|
||||||
|
newDevice.setDeviceType(device.getDeviceType());
|
||||||
|
newDevice.setIccId(device.getIccId());
|
||||||
|
newDevice.setBindTime(device.getBindTime());
|
||||||
|
newDevice.setDeadTime(device.getDeadTime());
|
||||||
|
newDevice.setPondId(null);
|
||||||
|
newDevice.setSalinityCompensation(0.0);
|
||||||
|
newDevice.setOxyWarnLower(device.getOxyWarnLower());
|
||||||
|
newDevice.setOxyWarnCallOpen(0);
|
||||||
|
newDevice.setOxyWarnCallNoDis(0);
|
||||||
|
newDevice.setTempWarnCallOpen(0);
|
||||||
|
newDevice.setTempWarnCallNoDis(0);
|
||||||
|
newDevice.setWarnCode(DefineDeviceWarnCode.None);
|
||||||
|
newDevice.setCategory(device.getCategory());
|
||||||
|
baseMapper.insert(newDevice);
|
||||||
|
log.info("已为用户重建无绑定设备: oldDeviceId={}, newDeviceId={}, serialNum={}",
|
||||||
|
deviceId, newDevice.getId(), device.getSerialNum());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("重建无绑定设备失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 清除告警数据(Redis离线等待标记)
|
||||||
|
try {
|
||||||
|
String serialNum = device.getSerialNum();
|
||||||
|
if (StringUtils.isNotBlank(serialNum)) {
|
||||||
|
RedisUtils.deleteObject(DEVICE_OFFLINE_WAIT_KEY_PREFIX + serialNum);
|
||||||
|
RedisUtils.deleteObject(DETECTOR_OXY_OFFLINE_WAIT_KEY_PREFIX + serialNum);
|
||||||
|
log.info("已清除设备Redis告警标记: serialNum={}", serialNum);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("清除Redis告警标记失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. 记录操作日志
|
||||||
|
try {
|
||||||
|
MessageOpRecordUtil.addMessageOpRecordUser(
|
||||||
|
device.getUserId(), device.getUserId(),
|
||||||
|
"设备操作",
|
||||||
|
String.format("%s(%s),解除绑定。", device.getDeviceName(), device.getSerialNum())
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("记录操作日志失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. 最后删除设备
|
return true;
|
||||||
return baseMapper.deleteByIds(ids) > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user