fix: 绑定功能优化完善,新增清零功能接口。
This commit is contained in:
@@ -107,6 +107,14 @@
|
||||
<artifactId>intc-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TDengine 模块(用于清理设备时序数据) -->
|
||||
<dependency>
|
||||
<groupId>com.intc</groupId>
|
||||
<artifactId>intc-tdengine</artifactId>
|
||||
<version>5.5.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -30,18 +30,25 @@ import com.intc.fishery.domain.vo.PublicDeviceLinkedCtrl;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceDeadInfo;
|
||||
import com.intc.fishery.domain.vo.PublicDeviceTypeAndSerialNum;
|
||||
import com.intc.fishery.domain.Device;
|
||||
import com.intc.fishery.domain.DeviceBindRecord;
|
||||
import com.intc.fishery.domain.DeviceSwitch;
|
||||
import com.intc.fishery.domain.DeviceErrorCode;
|
||||
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.DeviceBindRecordMapper;
|
||||
import com.intc.fishery.mapper.DeviceErrorCodeMapper;
|
||||
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.intc.fishery.utils.MessageOpRecordUtil;
|
||||
import com.intc.common.core.config.properties.DeviceTypeProperties;
|
||||
import com.intc.common.redis.utils.RedisUtils;
|
||||
import com.intc.tdengine.service.IDeviceSensorDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -69,8 +76,13 @@ public class DeviceController extends BaseController {
|
||||
private final PondMapper pondMapper;
|
||||
private final LinkedCtrlMapper linkedCtrlMapper;
|
||||
private final DeviceCorrectRecordMapper deviceCorrectRecordMapper;
|
||||
private final DeviceBindRecordMapper deviceBindRecordMapper;
|
||||
private final DeviceErrorCodeMapper deviceErrorCodeMapper;
|
||||
private final DeviceTypeProperties deviceTypeProperties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IDeviceSensorDataService deviceSensorDataService;
|
||||
|
||||
/**
|
||||
* 查询设备管理列表
|
||||
*/
|
||||
@@ -148,6 +160,106 @@ public class DeviceController extends BaseController {
|
||||
return toAjax(deviceService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清零设备测试数据(出厂测试用)
|
||||
* <p>清理范围:
|
||||
* <ul>
|
||||
* <li>有效期(deadTime)、告警状态(warnCode)、实时传感器值、最后上数时间</li>
|
||||
* <li>TDengine时序数据(删除设备子表,清除所有历史传感器数据)</li>
|
||||
* <li>设备绑定/解绑记录</li>
|
||||
* <li>设备校准记录</li>
|
||||
* <li>设备故障码记录</li>
|
||||
* <li>Redis告警标记</li>
|
||||
* </ul>
|
||||
* 清零后,设备重新绑定时会自动重新计算365天有效期。</p>
|
||||
*
|
||||
* @param id 设备ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
@SaCheckPermission("fishery:device:edit")
|
||||
@Log(title = "设备管理", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/resetTestData/{id}")
|
||||
public R<Void> resetTestData(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
Device device = deviceMapper.selectById(id);
|
||||
if (device == null) {
|
||||
return R.fail("设备不存在");
|
||||
}
|
||||
|
||||
String serialNum = device.getSerialNum();
|
||||
|
||||
// 1. 清零设备表:有效期、告警状态、实时传感器值、最后上数时间
|
||||
deviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<Device>()
|
||||
.eq(Device::getId, id)
|
||||
.set(Device::getDeadTime, null)
|
||||
.set(Device::getWarnCode, DefineDeviceWarnCode.None)
|
||||
.set(Device::getLastReportTime, null)
|
||||
.set(Device::getValueDissolvedOxygen, null)
|
||||
.set(Device::getValueTemperature, null)
|
||||
.set(Device::getValueSaturability, null)
|
||||
.set(Device::getValuePh, null)
|
||||
.set(Device::getValueSalinity, null)
|
||||
.set(Device::getValueBattery, null)
|
||||
.set(Device::getIsOxygenWarnExist, 0)
|
||||
.set(Device::getIsTempWarnExist, 0)
|
||||
);
|
||||
|
||||
// 2. 删除TDengine时序数据(设备子表,含所有历史传感器数据)
|
||||
if (deviceSensorDataService != null && serialNum != null && !serialNum.isBlank()) {
|
||||
try {
|
||||
deviceSensorDataService.dropSubTable(serialNum);
|
||||
} catch (Exception e) {
|
||||
// TDengine清理失败不阻断主流程
|
||||
org.slf4j.LoggerFactory.getLogger(DeviceController.class)
|
||||
.warn("清理TDengine数据失败: deviceId={}, serialNum={}, error={}", id, serialNum, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 删除设备绑定/解绑记录
|
||||
deviceBindRecordMapper.delete(
|
||||
new LambdaQueryWrapper<DeviceBindRecord>()
|
||||
.eq(DeviceBindRecord::getSerialNum, serialNum)
|
||||
);
|
||||
|
||||
// 4. 删除设备校准记录
|
||||
deviceCorrectRecordMapper.delete(
|
||||
new LambdaQueryWrapper<DeviceCorrectRecord>()
|
||||
.eq(DeviceCorrectRecord::getDeviceId, id)
|
||||
);
|
||||
|
||||
// 5. 删除设备故障码记录
|
||||
deviceErrorCodeMapper.delete(
|
||||
new LambdaQueryWrapper<DeviceErrorCode>()
|
||||
.eq(DeviceErrorCode::getDeviceId, id)
|
||||
);
|
||||
|
||||
// 6. 清除Redis告警标记
|
||||
if (serialNum != null && !serialNum.isBlank()) {
|
||||
try {
|
||||
RedisUtils.deleteObject("device:offline:wait:" + serialNum);
|
||||
RedisUtils.deleteObject("device:detector:oxy:offline:wait:" + serialNum);
|
||||
} catch (Exception e) {
|
||||
// Redis清理失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
// 7. 记录操作日志
|
||||
if (device.getUserId() != null) {
|
||||
MessageOpRecordUtil.addMessageOpRecordUser(
|
||||
device.getUserId(),
|
||||
"设备管理",
|
||||
String.format("%s(%s),清零设备测试数据。", device.getDeviceName(), serialNum)
|
||||
);
|
||||
} else {
|
||||
org.slf4j.LoggerFactory.getLogger(DeviceController.class)
|
||||
.info("清零设备测试数据(设备未绑定用户): deviceId={}, serialNum={}", id, serialNum);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户所有设备简化列表
|
||||
* type=1: 返回完整信息(包含塘口信息和开关列表)
|
||||
|
||||
@@ -402,6 +402,9 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
try {
|
||||
AquUser user = aquUserMapper.selectById(device.getUserId());
|
||||
if (user != null) {
|
||||
// 管理员(出厂测试人员)解绑时清空有效期,普通用户解绑时保留有效期(防止解绑续命)
|
||||
boolean isManager = user.getIsManager() != null && user.getIsManager() == 1L;
|
||||
|
||||
Device newDevice = new Device();
|
||||
newDevice.setUserId(null);
|
||||
newDevice.setIsOxygenUsed(device.getIsOxygenUsed());
|
||||
@@ -411,7 +414,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
newDevice.setDeviceType(device.getDeviceType());
|
||||
newDevice.setIccId(device.getIccId());
|
||||
newDevice.setBindTime(device.getBindTime());
|
||||
newDevice.setDeadTime(device.getDeadTime());
|
||||
// 管理员解绑时清空有效期(出厂测试),普通用户解绑时保留有效期
|
||||
newDevice.setDeadTime(isManager ? null : device.getDeadTime());
|
||||
newDevice.setPondId(null);
|
||||
newDevice.setSalinityCompensation(0.0);
|
||||
newDevice.setOxyWarnLower(device.getOxyWarnLower());
|
||||
@@ -423,8 +427,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
newDevice.setWarnCode(DefineDeviceWarnCode.None);
|
||||
newDevice.setCategory(device.getCategory());
|
||||
baseMapper.insert(newDevice);
|
||||
log.info("已为用户重建无绑定设备: oldDeviceId={}, newDeviceId={}, serialNum={}",
|
||||
deviceId, newDevice.getId(), device.getSerialNum());
|
||||
log.info("已为用户重建无绑定设备: oldDeviceId={}, newDeviceId={}, serialNum={}, isManager={}, deadTime={}",
|
||||
deviceId, newDevice.getId(), device.getSerialNum(), isManager, newDevice.getDeadTime());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("重建无绑定设备失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||
|
||||
@@ -1151,11 +1151,12 @@ public class IotController extends BaseController {
|
||||
device.setIotId(iotId);
|
||||
device.setSerialNum(bo.getSerialNum());
|
||||
device.setDeviceType(2); // 2-测控一体机
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000)); // 一年后到期
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
// 检查是否已过期
|
||||
if (device.getDeadTime() != null && now.after(device.getDeadTime())) {
|
||||
warnCode |= DefineDeviceWarnCode.DeviceTimeDead;
|
||||
// 管理员解绑会清空有效期(null),普通用户解绑会保留有效期。仅null时才设置365天
|
||||
if (device.getDeadTime() == null) {
|
||||
log.info("测控一体机重新绑定,有效期已被管理员解绑清空,重新设置: serialNum={}", bo.getSerialNum());
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1575,12 +1576,13 @@ public class IotController extends BaseController {
|
||||
device.setIotId(iotId);
|
||||
device.setSerialNum(bo.getSerialNum());
|
||||
device.setDeviceType(1); // 1-水质检测仪
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000)); // 一年后到期
|
||||
device.setIsOxygenUsed(1);
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
// 检查是否已过期
|
||||
if (device.getDeadTime() != null && now.after(device.getDeadTime())) {
|
||||
warnCode |= DefineDeviceWarnCode.DeviceTimeDead;
|
||||
// 管理员解绑会清空有效期(null),普通用户解绑会保留有效期。仅null时才设置365天
|
||||
if (device.getDeadTime() == null) {
|
||||
log.info("水质检测仪重新绑定,有效期已被管理员解绑清空,重新设置: serialNum={}", bo.getSerialNum());
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1832,7 +1834,13 @@ public class IotController extends BaseController {
|
||||
device.setIotId(iotId);
|
||||
device.setSerialNum(bo.getSerialNum());
|
||||
device.setDeviceType(3); // 3-太阳能网控
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000)); // 一年后到期
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
// 管理员解绑会清空有效期(null),普通用户解绑会保留有效期。仅null时才设置365天
|
||||
if (device.getDeadTime() == null) {
|
||||
log.info("太阳能网控重新绑定,有效期已被管理员解绑清空,重新设置: serialNum={}", bo.getSerialNum());
|
||||
device.setDeadTime(new Date(now.getTime() + 365L * 24 * 60 * 60 * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
// 设置基本信息
|
||||
|
||||
@@ -87,4 +87,13 @@ public interface DeviceSensorDataMapper {
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
DeviceSensorData getLatestReportTime(@Param("serialNum") String serialNum);
|
||||
|
||||
/**
|
||||
* 删除设备子表(清除该设备的所有时序数据)
|
||||
*
|
||||
* @param serialNum 设备序列号
|
||||
*/
|
||||
@DS("taos")
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
void dropSubTable(@Param("serialNum") String serialNum);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,4 +46,11 @@ public interface IDeviceSensorDataService {
|
||||
* @return 最新上数时间字符串,格式 yyyy-MM-dd HH:mm:ss;无数据时返回 null
|
||||
*/
|
||||
String getLatestReportTime(String serialNum);
|
||||
|
||||
/**
|
||||
* 删除设备子表(清除该设备的所有时序数据)
|
||||
*
|
||||
* @param serialNum 设备序列号
|
||||
*/
|
||||
void dropSubTable(String serialNum);
|
||||
}
|
||||
|
||||
@@ -296,4 +296,27 @@ public class DeviceSensorDataService implements IDeviceSensorDataService {
|
||||
default: return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除设备子表(清除该设备的所有时序数据)
|
||||
*/
|
||||
@Override
|
||||
public void dropSubTable(String serialNum) {
|
||||
if (serialNum == null || serialNum.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
deviceSensorDataMapper.dropSubTable(serialNum);
|
||||
// 清除建表缓存,下次插入数据时会重新建表
|
||||
CREATED_TABLES.remove(serialNum);
|
||||
log.info("已删除设备TDengine子表: serialNum={}", serialNum);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = e.getMessage();
|
||||
if (errorMsg != null && errorMsg.toLowerCase().contains("not exist")) {
|
||||
log.debug("设备TDengine子表不存在,无需删除: serialNum={}", serialNum);
|
||||
} else {
|
||||
log.warn("删除设备TDengine子表失败: serialNum={}, error={}", serialNum, errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,4 +120,8 @@
|
||||
ORDER BY `time` DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<update id="dropSubTable">
|
||||
DROP TABLE IF EXISTS `fishery`.`t_${serialNum}`
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user