fix: 设备管理,新增物理删除接口。

This commit is contained in:
tianyongbao
2026-07-12 09:32:01 +08:00
parent 143dcd8e63
commit 919bf2fb03
3 changed files with 168 additions and 1 deletions

View File

@@ -148,7 +148,7 @@ public class DeviceController extends BaseController {
}
/**
* 删除设备管理
* 删除设备管理解绑模式删除后重建设备记录保留IoT信息
*
* @param ids 主键串
*/
@@ -160,6 +160,39 @@ public class DeviceController extends BaseController {
return toAjax(deviceService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 彻底删除设备及其所有关联数据(物理删除,不重建设备记录)
* <p>删除范围:设备记录、开关、定时控制、联动控制、故障码记录、校准记录、绑定/解绑记录、TDengine时序数据、Redis告警标记
* <p>与普通删除的区别:不重建设备记录,设备彻底从系统中移除</p>
*
* @param ids 主键串
* @return 操作结果
*/
@SaCheckPermission("fishery:device:remove")
@Log(title = "设备管理", businessType = BusinessType.DELETE)
@DeleteMapping("/hard_delete/{ids}")
public R<Void> hardDelete(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
// 1. 删除TDengine时序数据需在设备记录删除前通过serialNum清理
if (deviceSensorDataService != null) {
for (Long id : ids) {
Device device = deviceMapper.selectById(id);
if (device != null && device.getSerialNum() != null && !device.getSerialNum().isBlank()) {
try {
deviceSensorDataService.dropSubTable(device.getSerialNum());
} catch (Exception e) {
org.slf4j.LoggerFactory.getLogger(DeviceController.class)
.warn("彻底删除-清理TDengine数据失败: deviceId={}, serialNum={}, error={}",
id, device.getSerialNum(), e.getMessage());
}
}
}
}
// 2. 执行彻底删除设备记录、关联数据、Redis标记
return toAjax(deviceService.hardDeleteByIds(List.of(ids)));
}
/**
* 清零设备测试数据(出厂测试用)
* <p>清理范围:

View File

@@ -65,4 +65,13 @@ public interface IDeviceService {
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 彻底删除设备及其所有关联数据(不重建设备记录)
* <p>删除范围设备记录、开关、定时控制、联动控制、故障码记录、校准记录、绑定记录、Redis告警标记</p>
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
Boolean hardDeleteByIds(Collection<Long> ids);
}

View File

@@ -462,7 +462,132 @@ public class DeviceServiceImpl implements IDeviceService {
return true;
}
/**
* 彻底删除设备及其所有关联数据(不重建设备记录)
* 与 deleteWithValidByIds 的区别:
* - 不插入解绑记录
* - 不重建无绑定设备
* - 额外删除该设备的所有绑定/解绑记录
* 设备关联数据全部清除包括联动控制、故障码、校准记录、开关、定时控制、绑定记录、Redis告警标记
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean hardDeleteByIds(Collection<Long> ids) {
// 1. 先查询完整设备信息(删除前需要用到各字段)
List<Device> devicesToDelete = baseMapper.selectList(
new LambdaQueryWrapper<Device>()
.in(Device::getId, ids)
);
if (devicesToDelete.isEmpty()) {
return false;
}
for (Device device : devicesToDelete) {
Long deviceId = device.getId();
// 2. 删除设备关联的联动控制
linkedCtrlMapper.delete(
new LambdaQueryWrapper<LinkedCtrl>()
.eq(LinkedCtrl::getDeviceId, deviceId)
);
// 3. 删除设备关联的故障码记录
deviceErrorCodeMapper.delete(
new LambdaQueryWrapper<DeviceErrorCode>()
.eq(DeviceErrorCode::getDeviceId, deviceId)
);
// 4. 删除设备关联的校准记录
deviceCorrectRecordMapper.delete(
new LambdaQueryWrapper<DeviceCorrectRecord>()
.eq(DeviceCorrectRecord::getDeviceId, deviceId)
);
// 5. 删除设备关联的开关、定时控制、联动绑定
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)
);
}
// 6. 删除该设备的所有绑定/解绑记录
if (StringUtils.isNotBlank(device.getSerialNum())) {
deviceBindRecordMapper.delete(
new LambdaQueryWrapper<DeviceBindRecord>()
.eq(DeviceBindRecord::getSerialNum, device.getSerialNum())
);
}
// 7. 物理删除设备记录
baseMapper.deleteById(deviceId);
// 8. 清除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);
}
// 9. 记录操作日志
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);
}
}
return true;
}
/**
* 计算设备列表的过期信息