2026-01-17 13:05:43 +08:00
|
|
|
|
package com.ruoyi.device.service.impl;
|
|
|
|
|
|
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import com.ruoyi.device.domain.api.IAircraftDomain;
|
|
|
|
|
|
import com.ruoyi.device.domain.api.IDeviceDomain;
|
|
|
|
|
|
import com.ruoyi.device.domain.api.IDockAircraftDomain;
|
|
|
|
|
|
import com.ruoyi.device.domain.api.IDockDomain;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import com.ruoyi.device.domain.api.IThingsBoardDomain;
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import com.ruoyi.device.domain.model.Aircraft;
|
|
|
|
|
|
import com.ruoyi.device.domain.model.Device;
|
|
|
|
|
|
import com.ruoyi.device.domain.model.Dock;
|
|
|
|
|
|
import com.ruoyi.device.domain.model.DockAircraft;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import com.ruoyi.device.domain.model.thingsboard.AttributeMap;
|
|
|
|
|
|
import com.ruoyi.device.domain.model.thingsboard.DeviceInfo;
|
|
|
|
|
|
import com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes;
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import com.ruoyi.device.service.enums.DeviceType;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
2026-01-17 14:08:11 +08:00
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import org.springframework.util.StringUtils;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
|
2026-01-17 14:08:11 +08:00
|
|
|
|
import java.util.ArrayList;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import java.util.List;
|
2026-01-17 13:57:14 +08:00
|
|
|
|
import java.util.Objects;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
import java.util.Optional;
|
2026-01-17 14:08:11 +08:00
|
|
|
|
import java.util.regex.Pattern;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
|
public class SynService {
|
|
|
|
|
|
|
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(SynService.class);
|
|
|
|
|
|
|
|
|
|
|
|
private final IThingsBoardDomain iThingsBoardDomain;
|
|
|
|
|
|
|
2026-01-17 14:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 设备名称过滤正则表达式列表(从配置文件读取)
|
|
|
|
|
|
* 匹配这些正则表达式的设备将被跳过,不进行同步
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Value("${device.sync.exclude-patterns:}")
|
|
|
|
|
|
private String excludePatterns;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 编译后的正则表达式模式列表(延迟初始化)
|
|
|
|
|
|
*/
|
|
|
|
|
|
private List<Pattern> excludePatternList;
|
|
|
|
|
|
|
2026-01-17 13:57:14 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private IDeviceDomain deviceDomain;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private IDockDomain dockDomain;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private IAircraftDomain aircraftDomain;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private IDockAircraftDomain dockAircraftDomain;
|
|
|
|
|
|
|
2026-01-17 13:05:43 +08:00
|
|
|
|
public SynService(IThingsBoardDomain iThingsBoardDomain) {
|
|
|
|
|
|
this.iThingsBoardDomain = iThingsBoardDomain;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-17 14:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 初始化设备名称过滤正则表达式列表
|
|
|
|
|
|
* 延迟初始化,在第一次使用时编译正则表达式
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void initExcludePatterns() {
|
|
|
|
|
|
if (excludePatternList == null) {
|
|
|
|
|
|
excludePatternList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.hasText(excludePatterns)) {
|
|
|
|
|
|
String[] patterns = excludePatterns.split(",");
|
|
|
|
|
|
for (String pattern : patterns) {
|
|
|
|
|
|
String trimmedPattern = pattern.trim();
|
|
|
|
|
|
if (StringUtils.hasText(trimmedPattern)) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
excludePatternList.add(Pattern.compile(trimmedPattern));
|
|
|
|
|
|
log.info("加载设备名称过滤规则: {}", trimmedPattern);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("无效的正则表达式: {}, error={}", trimmedPattern, e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (excludePatternList.isEmpty()) {
|
|
|
|
|
|
log.info("未配置设备名称过滤规则");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 判断设备名称是否应该被过滤(跳过同步)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceName 设备名称
|
|
|
|
|
|
* @return true 表示应该被过滤,false 表示不过滤
|
|
|
|
|
|
*/
|
|
|
|
|
|
private boolean shouldExcludeDevice(String deviceName) {
|
|
|
|
|
|
// 延迟初始化
|
|
|
|
|
|
initExcludePatterns();
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有配置过滤规则,不过滤任何设备
|
|
|
|
|
|
if (excludePatternList.isEmpty()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查设备名称是否匹配任何过滤规则
|
|
|
|
|
|
for (Pattern pattern : excludePatternList) {
|
|
|
|
|
|
if (pattern.matcher(deviceName).matches()) {
|
|
|
|
|
|
log.debug("设备 {} 匹配过滤规则 {},跳过同步", deviceName, pattern.pattern());
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-17 13:05:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 定时任务:同步基础表数据
|
|
|
|
|
|
* 执行时间:启动后1分钟开始,每2分钟执行一次(可通过配置文件修改)
|
|
|
|
|
|
* 配置项:device.schedule.print-devices.initial-delay 初始延迟时间(毫秒)
|
|
|
|
|
|
* device.schedule.print-devices.fixed-delay 执行间隔时间(毫秒)
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Scheduled(initialDelayString = "${device.schedule.update-devices.initial-delay:60000}",
|
|
|
|
|
|
fixedDelayString = "${device.schedule.update-devices.fixed-delay:120000}")
|
|
|
|
|
|
public void updateDevicesScheduled() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
log.info("========== 开始执行定时任务:同步基础表数据 ==========");
|
|
|
|
|
|
|
|
|
|
|
|
Iterable<List<DeviceInfo>> allDevices = iThingsBoardDomain.getAllDevices();
|
|
|
|
|
|
int totalCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (List<DeviceInfo> deviceBatch : allDevices) {
|
2026-01-17 13:57:14 +08:00
|
|
|
|
for (DeviceInfo deviceInfo : deviceBatch) {
|
2026-01-17 14:08:11 +08:00
|
|
|
|
// 通过设备名字,过滤出不需要同步的一些设备,比如
|
|
|
|
|
|
// 设备名字是 THJSQ03A2302FAWQZBJ1 和 THJSQ03A23045BLPGYC5
|
|
|
|
|
|
// 支持配置简单的正则表达式;该正则表达式需要维护在配置文件中
|
|
|
|
|
|
|
|
|
|
|
|
// 检查设备名称是否应该被过滤
|
|
|
|
|
|
if (shouldExcludeDevice(deviceInfo.getName())) {
|
|
|
|
|
|
log.info("设备 {} 匹配过滤规则,跳过同步", deviceInfo.getName());
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-17 13:05:43 +08:00
|
|
|
|
try {
|
2026-01-17 13:57:14 +08:00
|
|
|
|
// 获取设备属性
|
|
|
|
|
|
AttributeMap attributes = iThingsBoardDomain.getDeviceAttributes(deviceInfo.getId());
|
|
|
|
|
|
|
|
|
|
|
|
// 判断设备类型
|
|
|
|
|
|
DeviceType deviceType = determineDeviceType(deviceInfo, attributes);
|
|
|
|
|
|
|
|
|
|
|
|
// 同步设备表
|
|
|
|
|
|
Long deviceId = syncDevice(deviceInfo, attributes, deviceType);
|
|
|
|
|
|
|
|
|
|
|
|
// 根据设备类型进行不同的处理
|
|
|
|
|
|
if (deviceType == DeviceType.DOCK) {
|
|
|
|
|
|
// 机场:同步机场表
|
|
|
|
|
|
syncDock(deviceId, deviceInfo.getName());
|
|
|
|
|
|
|
|
|
|
|
|
// 获取机场挂载的无人机SN号
|
|
|
|
|
|
Optional<String> subDeviceSnOpt = attributes.get(DeviceAttributes.SUB_DEVICE_SN);
|
|
|
|
|
|
if (subDeviceSnOpt.isPresent() && StringUtils.hasText(subDeviceSnOpt.get())) {
|
|
|
|
|
|
String aircraftSn = subDeviceSnOpt.get();
|
|
|
|
|
|
// 通过SN号查找无人机设备
|
|
|
|
|
|
Device aircraftDevice = findDeviceBySn(aircraftSn);
|
|
|
|
|
|
if (aircraftDevice != null) {
|
|
|
|
|
|
// 同步机场无人机关联
|
|
|
|
|
|
syncDockAircraft(deviceId, aircraftDevice.getDeviceId());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (deviceType == DeviceType.AIRCRAFT) {
|
|
|
|
|
|
// 无人机:同步无人机表
|
|
|
|
|
|
syncAircraft(deviceId, deviceInfo.getName());
|
2026-01-17 13:05:43 +08:00
|
|
|
|
}
|
2026-01-17 13:57:14 +08:00
|
|
|
|
// 网关类型不需要额外处理
|
|
|
|
|
|
totalCount++;
|
2026-01-17 13:05:43 +08:00
|
|
|
|
} catch (Exception e) {
|
2026-01-17 13:57:14 +08:00
|
|
|
|
log.error("同步设备失败: deviceId={}, deviceName={}, error={}",
|
|
|
|
|
|
deviceInfo.getId(), deviceInfo.getName(), e.getMessage(), e);
|
2026-01-17 13:05:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-17 13:57:14 +08:00
|
|
|
|
log.info("========== 数据同步任务完成,共同步 {} 个设备 ==========", totalCount);
|
2026-01-17 13:05:43 +08:00
|
|
|
|
} catch (Exception e) {
|
2026-01-17 13:57:14 +08:00
|
|
|
|
log.error("数据同步任务执行失败: {}", e.getMessage(), e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 判断设备类型
|
|
|
|
|
|
* 优化后的判断逻辑:
|
|
|
|
|
|
* 1. 优先使用 ThingsBoard 标准的 additionalInfo.gateway 字段判断网关
|
|
|
|
|
|
* 2. 对于非网关设备,通过 dock_sn 属性区分机场和无人机
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceInfo ThingsBoard设备信息
|
|
|
|
|
|
* @param attributes 设备属性
|
|
|
|
|
|
* @return 设备类型
|
|
|
|
|
|
*/
|
|
|
|
|
|
private DeviceType determineDeviceType(DeviceInfo deviceInfo, AttributeMap attributes) {
|
|
|
|
|
|
String deviceName = deviceInfo.getName();
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 使用 ThingsBoard 标准方式判断网关:检查 additionalInfo 中的 gateway 字段
|
|
|
|
|
|
if (deviceInfo.isGateway()) {
|
|
|
|
|
|
return DeviceType.GATEWAY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 非网关设备:通过 dock_sn 属性区分机场和无人机
|
|
|
|
|
|
Optional<String> dockSnOpt = attributes.get(DeviceAttributes.DOCK_SN);
|
|
|
|
|
|
|
|
|
|
|
|
if (dockSnOpt.isPresent() && StringUtils.hasText(dockSnOpt.get())) {
|
|
|
|
|
|
String dockSn = dockSnOpt.get();
|
|
|
|
|
|
// dock_sn 等于设备名称 -> 机场
|
|
|
|
|
|
// dock_sn 不等于设备名称 -> 无人机(挂载在该机场下)
|
|
|
|
|
|
return deviceName.equals(dockSn) ? DeviceType.DOCK : DeviceType.AIRCRAFT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// dock_sn 属性不存在或为空,无法判断设备类型
|
|
|
|
|
|
throw new IllegalStateException("无法确定设备类型:设备 " + deviceName + " 缺少 dock_sn 属性");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 同步设备数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceInfo ThingsBoard设备信息
|
|
|
|
|
|
* @param attributes 设备属性
|
|
|
|
|
|
* @param deviceType 设备类型
|
|
|
|
|
|
* @return 设备主键ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
private Long syncDevice(DeviceInfo deviceInfo, AttributeMap attributes, DeviceType deviceType) {
|
|
|
|
|
|
String iotDeviceId = deviceInfo.getId();
|
|
|
|
|
|
String deviceName = deviceInfo.getName();
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 ThingsBoard 标准方式获取网关设备ID(通过 EntityRelation)
|
|
|
|
|
|
String gateway = iThingsBoardDomain.getDeviceGatewayId(iotDeviceId);
|
|
|
|
|
|
|
|
|
|
|
|
String deviceSn = deviceName; // 使用设备名称作为SN号,网关其实是没有SN号的
|
|
|
|
|
|
|
|
|
|
|
|
// 查询设备是否已存在
|
|
|
|
|
|
Device existingDevice = deviceDomain.selectDeviceByIotDeviceId(iotDeviceId);
|
|
|
|
|
|
|
|
|
|
|
|
if (existingDevice == null) {
|
|
|
|
|
|
// 设备不存在,插入新设备
|
|
|
|
|
|
Device newDevice = new Device();
|
|
|
|
|
|
newDevice.setDeviceName(deviceName);
|
|
|
|
|
|
newDevice.setIotDeviceId(iotDeviceId);
|
|
|
|
|
|
newDevice.setDeviceType(deviceType.getCode());
|
|
|
|
|
|
newDevice.setDeviceSn(deviceSn);
|
|
|
|
|
|
newDevice.setGateway(gateway);
|
|
|
|
|
|
newDevice.setCreateBy("system");
|
|
|
|
|
|
|
|
|
|
|
|
deviceDomain.insertDevice(newDevice);
|
|
|
|
|
|
log.info("插入新设备: iotDeviceId={}, deviceName={}, deviceType={}", iotDeviceId, deviceName, deviceType);
|
|
|
|
|
|
return newDevice.getDeviceId();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 设备已存在,检查是否需要更新
|
|
|
|
|
|
boolean needUpdate = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!Objects.equals(existingDevice.getDeviceName(), deviceName)) {
|
|
|
|
|
|
existingDevice.setDeviceName(deviceName);
|
|
|
|
|
|
needUpdate = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!Objects.equals(existingDevice.getDeviceType(), deviceType.getCode())) {
|
|
|
|
|
|
existingDevice.setDeviceType(deviceType.getCode());
|
|
|
|
|
|
needUpdate = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!Objects.equals(existingDevice.getDeviceSn(), deviceSn)) {
|
|
|
|
|
|
existingDevice.setDeviceSn(deviceSn);
|
|
|
|
|
|
needUpdate = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!Objects.equals(existingDevice.getGateway(), gateway)) {
|
|
|
|
|
|
existingDevice.setGateway(gateway);
|
|
|
|
|
|
needUpdate = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (needUpdate) {
|
|
|
|
|
|
existingDevice.setUpdateBy("system");
|
|
|
|
|
|
deviceDomain.updateDevice(existingDevice);
|
|
|
|
|
|
log.info("更新设备: iotDeviceId={}, deviceName={}, deviceType={}", iotDeviceId, deviceName, deviceType);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return existingDevice.getDeviceId();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 同步机场数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceId 设备主键ID
|
|
|
|
|
|
* @param deviceName 设备名称
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void syncDock(Long deviceId, String deviceName) {
|
|
|
|
|
|
// 查询机场是否已存在
|
|
|
|
|
|
Dock existingDock = dockDomain.selectDockByDeviceId(deviceId);
|
|
|
|
|
|
|
|
|
|
|
|
if (existingDock == null) {
|
|
|
|
|
|
// 机场不存在,插入新机场
|
|
|
|
|
|
Dock newDock = new Dock();
|
|
|
|
|
|
newDock.setDockName(deviceName);
|
|
|
|
|
|
newDock.setDeviceId(deviceId);
|
|
|
|
|
|
newDock.setCreateBy("system");
|
|
|
|
|
|
|
|
|
|
|
|
dockDomain.insertDock(newDock);
|
|
|
|
|
|
log.info("插入新机场: deviceId={}, dockName={}", deviceId, deviceName);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 机场已存在,无需更新
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 同步无人机数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceId 设备主键ID
|
|
|
|
|
|
* @param deviceName 设备名称
|
|
|
|
|
|
* @return 无人机主键ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
private Long syncAircraft(Long deviceId, String deviceName) {
|
|
|
|
|
|
// 查询无人机是否已存在
|
|
|
|
|
|
Aircraft existingAircraft = aircraftDomain.selectAircraftByDeviceId(deviceId);
|
|
|
|
|
|
|
|
|
|
|
|
if (existingAircraft == null) {
|
|
|
|
|
|
// 无人机不存在,插入新无人机
|
|
|
|
|
|
Aircraft newAircraft = new Aircraft();
|
|
|
|
|
|
newAircraft.setAircraftName(deviceName);
|
|
|
|
|
|
newAircraft.setDeviceId(deviceId);
|
|
|
|
|
|
newAircraft.setCreateBy("system");
|
|
|
|
|
|
|
|
|
|
|
|
aircraftDomain.insertAircraft(newAircraft);
|
|
|
|
|
|
log.info("插入新无人机: deviceId={}, aircraftName={}", deviceId, deviceName);
|
|
|
|
|
|
return newAircraft.getAircraftId();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 无人机已存在,无需更新
|
|
|
|
|
|
return existingAircraft.getAircraftId();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据设备SN号查找设备
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param deviceSn 设备SN号
|
|
|
|
|
|
* @return 设备信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
private Device findDeviceBySn(String deviceSn) {
|
|
|
|
|
|
Device queryDevice = new Device();
|
|
|
|
|
|
queryDevice.setDeviceSn(deviceSn);
|
|
|
|
|
|
List<Device> devices = deviceDomain.selectDeviceList(queryDevice);
|
|
|
|
|
|
return (devices != null && !devices.isEmpty()) ? devices.get(0) : null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 同步机场无人机关联数据
|
|
|
|
|
|
* 按照一个机场只会挂载一台无人机的逻辑进行处理
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param dockDeviceId 机场设备主键ID
|
|
|
|
|
|
* @param aircraftDeviceId 无人机设备主键ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
private void syncDockAircraft(Long dockDeviceId, Long aircraftDeviceId) {
|
|
|
|
|
|
// 获取机场主键
|
|
|
|
|
|
Dock dock = dockDomain.selectDockByDeviceId(dockDeviceId);
|
|
|
|
|
|
if (dock == null) {
|
|
|
|
|
|
log.warn("机场不存在,无法同步机场无人机关联: dockDeviceId={}", dockDeviceId);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取无人机主键
|
|
|
|
|
|
Aircraft aircraft = aircraftDomain.selectAircraftByDeviceId(aircraftDeviceId);
|
|
|
|
|
|
if (aircraft == null) {
|
|
|
|
|
|
log.warn("无人机不存在,无法同步机场无人机关联: aircraftDeviceId={}", aircraftDeviceId);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Long dockId = dock.getDockId();
|
|
|
|
|
|
Long aircraftId = aircraft.getAircraftId();
|
|
|
|
|
|
|
|
|
|
|
|
// 查询该机场是否已有关联
|
|
|
|
|
|
List<DockAircraft> existingRelations = dockAircraftDomain.selectDockAircraftByDockId(dockId);
|
|
|
|
|
|
|
|
|
|
|
|
if (existingRelations == null || existingRelations.isEmpty()) {
|
|
|
|
|
|
// 机场没有关联,插入新关联
|
|
|
|
|
|
DockAircraft newRelation = new DockAircraft();
|
|
|
|
|
|
newRelation.setDockId(dockId);
|
|
|
|
|
|
newRelation.setAircraftId(aircraftId);
|
|
|
|
|
|
newRelation.setCreateBy("system");
|
|
|
|
|
|
|
|
|
|
|
|
dockAircraftDomain.insertDockAircraft(newRelation);
|
|
|
|
|
|
log.info("插入机场无人机关联: dockId={}, aircraftId={}", dockId, aircraftId);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 机场已有关联,检查是否需要更新
|
|
|
|
|
|
DockAircraft existingRelation = existingRelations.get(0);
|
|
|
|
|
|
if (!Objects.equals(existingRelation.getAircraftId(), aircraftId)) {
|
|
|
|
|
|
// 无人机发生变化,更新关联
|
|
|
|
|
|
existingRelation.setAircraftId(aircraftId);
|
|
|
|
|
|
existingRelation.setUpdateBy("system");
|
|
|
|
|
|
dockAircraftDomain.updateDockAircraft(existingRelation);
|
|
|
|
|
|
log.info("更新机场无人机关联: dockId={}, aircraftId={}", dockId, aircraftId);
|
|
|
|
|
|
}
|
2026-01-17 13:05:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|