package com.maibu.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.maibu.core.business.Device; import com.maibu.core.business.device.NettyDevice; import com.maibu.core.domain.AjaxResult; import com.maibu.core.domain.entity.UserClient; import com.maibu.core.domain.model.LoginUser; import com.maibu.core.enums.ConnectorStatus; import com.maibu.exception.ServiceException; import com.maibu.mapper.DeviceMapper; import com.maibu.mapper.SysUserClientMapper; import com.maibu.memory.DeviceSessionManager; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import com.maibu.dto.*; import java.time.LocalDateTime; import java.util.Date; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Service @Slf4j public class TransferDeviceService { @Autowired private IDeviceService iDeviceService; @Autowired private ISysUserClientService sysUserClientService; @Autowired private DeviceSessionManager sessionManager; @Autowired private SysUserClientMapper userClientMapper; @Autowired private DeviceMapper deviceMapper; public AjaxResult bind(DeviceBindDTO bindDTO, LoginUser user) { try { String deviceId = bindDTO.getDeviceId(); String deviceAlias = bindDTO.getDeviceAlias(); //判断当前设备是否存 Device device = iDeviceService.selectDeviceBySerialNumber(deviceId); if (device == null) { return AjaxResult.error("设备不存在"); } else { Long tenantId = device.getTenantId(); if (tenantId != -1) { if (!tenantId.equals(user.getUserId())) { return AjaxResult.error("设备有其他用户绑定"); } } device.setTenantId(user.getUserId()); device.setTenantName(user.getUsername()); device.setUpdateTime(LocalDateTime.now()); device.setDeviceAlias(deviceAlias); device.setActiveTime(new Date()); iDeviceService.updateDeviceBySelf(device); // deviceMapper.updateById(device); return AjaxResult.success(true); } } catch (Exception e) { log.error("设备绑定失败: {}", e.getMessage(), e); return AjaxResult.error("设备绑定失败:" + e.getMessage()); } } public AjaxResult unbind(DeviceBindDTO bindDTO, LoginUser user) { try { String deviceId = bindDTO.getDeviceId(); //判断当前设备是否存 Device device = iDeviceService.selectDeviceBySerialNumber(deviceId); if (device == null) { return AjaxResult.error("设备不存在"); } else { Long tenantId = device.getTenantId(); if (tenantId == -1) { return AjaxResult.error("设备未绑定"); } if (!tenantId.equals(user.getUserId())) { return AjaxResult.error("无解绑权限"); } device.setTenantId(-1L); device.setTenantName(""); device.setUpdateTime(LocalDateTime.now()); device.setDeviceAlias(""); // deviceMapper.updateById(device); iDeviceService.updateDeviceBySelf(device); //判断是否正在控制 如果正在控制,删除控制状态 LambdaQueryWrapper lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.eq(UserClient::getDeviceName, deviceId); List users = userClientMapper.selectList(lambdaWrapper); log.info("users:{}", users); if (!CollectionUtils.isEmpty(users)) { users.forEach(userClient -> { log.info("userClient:{}", userClient); if (userClient != null) { String masterId = userClient.getClientName(); NettyDevice deviceMaster = sessionManager.getDevice(masterId); if (deviceMaster != null) { String oldSlave = userClient.getDeviceName(); //删除主的连接关系 deviceMaster.getConnectedConnectors().removeIf(x -> x.getConnectorId().equals(oldSlave)); //删除从的连接关系 NettyDevice oldSlaveDevice = sessionManager.getDevice(oldSlave); if (oldSlaveDevice != null && !CollectionUtils.isEmpty(oldSlaveDevice.getConnectedConnectors())) { Set connectedDevices = oldSlaveDevice.getConnectedConnectors(); connectedDevices.removeIf(x -> x.getConnectorId().equals(masterId)); } } sysUserClientService.updateAliveStatus(masterId, "", 0); log.info("updateById:{}", userClient.getClientName()); } }); } return AjaxResult.success(true); } } catch (Exception e) { log.error("设备解绑失败: {}", e.getMessage(), e); return AjaxResult.error("设备解绑失败:" + e.getMessage()); } } public AjaxResult updateDeviceAlias(DeviceBindDTO bindDTO, LoginUser user) { try { String deviceId = bindDTO.getDeviceId(); //判断当前设备是否存 Device device = iDeviceService.selectDeviceBySerialNumber(deviceId); if (device == null) { return AjaxResult.error("设备不存在"); } else { // Long tenantId = device.getTenantId(); // if (tenantId == -1) { // return AjaxResult.error("设备未绑定"); // } // if (!tenantId.equals(user.getUserId())) { // return AjaxResult.error("无操作权限"); // } device.setDeviceAlias(bindDTO.getDeviceAlias()); device.setUpdateTime(LocalDateTime.now()); device.setCreateBy(user.getUsername()); iDeviceService.updateDeviceBySelf(device); return AjaxResult.success(true); } } catch (Exception e) { log.error("设备更新失败: {}", e.getMessage(), e); return AjaxResult.error("设备更新失败:" + e.getMessage()); } } // public synchronized boolean switchDevice(DeviceBindDTO bindDTO, LoginUser user) { // try { // String slaveId = bindDTO.getDeviceId(); // String platform = bindDTO.getPlatform(); // String userName = user.getUsername(); // String masterId = userName + ":" + platform; // //todo 判断是否有权限 正在控制才能切 // //todo 离线没有控制权的怎么切 // log.info("switchDevice:{}", masterId); // NettyDevice deviceMaster = sessionManager.getDevice(masterId); // log.info("deviceMaster:{}", deviceMaster); // if (deviceMaster != null) { // log.info("ConnectorStatus:{}", deviceMaster.getConnectorStatus()); // if (ConnectorStatus.RECEIVER.equals(deviceMaster.getConnectorStatus())) { // //当前账号没有控制则可以切换为控制? // NettyDevice activeDevice = sessionManager.getUserControl(userName); // deviceMaster.getConnectedConnectors().clear(); // if (activeDevice == null) { // log.info("bindConnector ACTIVE :{}", masterId); // sessionManager.bindConnector(masterId, slaveId); // deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE); // deviceMaster.setCurrentSlaveId(slaveId); // sysUserClientService.updateAliveStatus(masterId, slaveId, 1); // } else { // log.info("bindConnector RECEIVER :{}", masterId); // sessionManager.bindConnector(masterId, slaveId); // deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER); // deviceMaster.setCurrentSlaveId(slaveId); // sysUserClientService.updateAliveStatus(masterId, slaveId, 2); // } // } else { // //从关联其他设备切换到 当前禁言 假如有控制且不是当前更新为2 // List controls = sessionManager.getSlaveControl(slaveId); // if (CollectionUtils.isEmpty(controls)) { // deviceMaster.getConnectedConnectors().clear(); // log.info("bindConnector 1:{}", masterId); // sessionManager.bindConnector(masterId, slaveId); // deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE); // deviceMaster.setCurrentSlaveId(slaveId); // sysUserClientService.updateAliveStatus(masterId, slaveId, 1); // } else { // NettyDevice controlDevice = controls.get(0); // if (!masterId.equals(controlDevice.getConnectorId())) { // //当前的设备有控制 的主机 // deviceMaster.getConnectedConnectors().clear(); // log.info("bindConnector RECEIVER 2:{}", masterId); // sessionManager.bindConnector(masterId, slaveId); // deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER); // deviceMaster.setCurrentSlaveId(slaveId); // sysUserClientService.updateAliveStatus(masterId, slaveId, 2); // } // //当前 切当前不做操作 // } // } // return true; // } // } catch (Exception e) { // log.error("切换设备失败: {}", e.getMessage(), e); // } // return false; // } public synchronized boolean switchDevice(DeviceBindDTO bindDTO) { try { String slaveId = bindDTO.getDeviceId(); // String platform = bindDTO.getPlatform(); // String userName = user.getUsername(); // String masterId = userName + ":" + platform; String token = bindDTO.getToken(); log.info("switchDevice slaveId:{},token:{}", slaveId, token); NettyDevice deviceMaster = sessionManager.getDevice(token); log.info("switchDevice deviceMaster:{}", deviceMaster); if (deviceMaster == null) { throw new ServiceException("功能码当前账号未发送登录请求,不在线"); } List controls = sessionManager.getAllSlaveControl(slaveId); if (CollectionUtils.isEmpty(controls)) { deviceMaster.getConnectedConnectors().clear(); sessionManager.bindConnector(token, slaveId); deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE); deviceMaster.setCurrentSlaveId(slaveId); sessionManager.lock(slaveId, token); log.info("switchDevice bindConnector slaveId:{},token:{}", slaveId, token); } else { List connectorIds = controls.stream().map(NettyDevice::getConnectorId).collect(Collectors.toList()); if (!connectorIds.contains(token)) { //当前的设备有控制 的主机 deviceMaster.getConnectedConnectors().clear(); sessionManager.bindConnector(token, slaveId); deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER); deviceMaster.setCurrentSlaveId(slaveId); log.info("switchDevice bindConnector RECEIVER :{}", token); } else { deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE); deviceMaster.setCurrentSlaveId(slaveId); sessionManager.lock(slaveId, token); } //当前 切当前不做操作 } return true; } catch (Exception e) { log.error("切换设备失败: {}", e.getMessage(), e); } return false; } public DeviceControlDTO remoteControl(DeviceBindDTO bindDTO) { try { String token = bindDTO.getToken(); String masterToken = sessionManager.getMaster(bindDTO.getDeviceId()); DeviceControlDTO dto = new DeviceControlDTO(); if (!StringUtils.isEmpty(token) && token.equals(masterToken)) { dto.setRemoteControl(true); dto.setOwner("you"); } else { dto.setRemoteControl(false); dto.setReason("occupied"); dto.setOwner(masterToken); } return dto; } catch (Exception e) { log.error("获取设备权限失败", e); } return null; } public DeviceSwitchControlDTO switchControl(DeviceBindDTO bindDTO, LoginUser user) { try { String slaveId = bindDTO.getDeviceId(); String platform = bindDTO.getPlatform(); String userName = user.getUsername(); String masterId = userName + ":" + platform; DeviceSwitchControlDTO dto = new DeviceSwitchControlDTO(); //收到明确的切换设备请求了 从哪边切换到另一边 //判断当前是否有控制的设备 NettyDevice masterDevice = sessionManager.getDevice(masterId); if (masterDevice == null || !masterDevice.getChannel().isActive()) { //主机已离线 dto.setSwitchControl(false); dto.setReason("主机已离线"); return dto; } NettyDevice slaveDevice = sessionManager.getDevice(slaveId); if (slaveDevice == null || !masterDevice.getChannel().isActive()) { //从机已离线 //主机已离线 dto.setSwitchControl(false); dto.setReason("从机已离线"); return dto; } List controlList = sessionManager.getSlaveControl(slaveId); if (!CollectionUtils.isEmpty(controlList)) { //如果当前设备有控制 controlList.forEach(c -> { if (!c.getConnectorId().equals(masterId)) { c.setCurrentSlaveId(null); c.removeConnectedDevice(slaveDevice); c.setConnectorStatus(ConnectorStatus.RECEIVER); sysUserClientService.updateAliveStatus(c.getConnectorId(), slaveId, 2); } }); } masterDevice.setCurrentSlaveId(slaveId); masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE); sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1); dto.setSwitchControl(true); dto.setHolder(platform); return dto; } catch (Exception e) { log.error(e.getMessage()); return new DeviceSwitchControlDTO(false); } } public void releaseControl(DeviceBindDTO bindDTO, LoginUser user) { try { String platform = bindDTO.getPlatform(); String userName = user.getUsername(); String masterId = userName + ":" + platform; Integer type = bindDTO.getType(); NettyDevice deviceMaster = sessionManager.getDevice(masterId); if (type != null && deviceMaster != null) { if (type == 1) { deviceMaster.setCurrentSlaveId(null); deviceMaster.getConnectedConnectors().clear(); } else if (type == 2) { deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER); } } sessionManager.unLock(bindDTO.getDeviceId(), bindDTO.getToken(), false); } catch (Exception e) { log.error(e.getMessage()); } } }