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.mybatis.core.page.PageQuery;
|
||||
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.Device;
|
||||
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.bo.DeviceBo;
|
||||
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.DeviceCorrectRecordMapper;
|
||||
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.TimingCtrlMapper;
|
||||
import com.intc.fishery.service.IDeviceService;
|
||||
import com.intc.fishery.utils.MessageOpRecordUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -49,6 +53,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
private final DeviceMapper baseMapper;
|
||||
private final AquUserMapper aquUserMapper;
|
||||
private final DeviceBindRecordMapper deviceBindRecordMapper;
|
||||
private final DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
private final DeviceErrorCodeMapper deviceErrorCodeMapper;
|
||||
@@ -56,6 +61,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
private final LinkedCtrlMapper linkedCtrlMapper;
|
||||
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 isValid 是否进行有效性校验
|
||||
@@ -234,85 +254,23 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
|
||||
// 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. 查询要删除的设备信息,添加解绑记录
|
||||
// 1. 先查询完整设备信息(删除前需要用到各字段)
|
||||
List<Device> devicesToDelete = baseMapper.selectList(
|
||||
new LambdaQueryWrapper<Device>()
|
||||
.in(Device::getId, ids)
|
||||
.select(Device::getId, Device::getUserId, Device::getIotId,
|
||||
Device::getDeviceType, Device::getSerialNum)
|
||||
);
|
||||
if (devicesToDelete.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 为每个设备添加解绑记录
|
||||
for (Device device : devicesToDelete) {
|
||||
Long deviceId = device.getId();
|
||||
|
||||
// 2. 新增解绑记录
|
||||
try {
|
||||
DeviceBindRecord unbindRecord = new DeviceBindRecord();
|
||||
unbindRecord.setUserId(device.getUserId());
|
||||
@@ -322,15 +280,135 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
unbindRecord.setSerialNum(device.getSerialNum());
|
||||
deviceBindRecordMapper.insert(unbindRecord);
|
||||
log.info("添加设备解绑记录: deviceId={}, userId={}, serialNum={}",
|
||||
device.getId(), device.getUserId(), device.getSerialNum());
|
||||
deviceId, device.getUserId(), device.getSerialNum());
|
||||
} 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 baseMapper.deleteByIds(ids) > 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user