package com.ard.work.service.control;
|
|
import com.ard.common.exception.ControlException;
|
import com.ard.common.utils.SecurityUtils;
|
import com.ard.system.service.ISysUserService;
|
import com.ard.work.component.websocket.handler.UavControlManager;
|
import com.ard.work.domain.message.UavControlType;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.Set;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
/**
|
* UAV控制服务类,负责管理对飞行和载荷的控制请求、释放和权限管理
|
* 支持优先级抢占
|
*/
|
@Service
|
public class UavControlService {
|
|
@Resource
|
private UavControlManager uavControlManager;
|
|
@Resource
|
private ISysUserService sysUserService;
|
|
/**
|
* 当前飞行控制权限用户
|
*/
|
private final ConcurrentHashMap<String, Long> uavFlyControlMap = new ConcurrentHashMap<>();
|
|
/**
|
* 当前载荷控制权限用户
|
*/
|
private final ConcurrentHashMap<String, Long> uavPayloadControlMap = new ConcurrentHashMap<>();
|
|
/**
|
* 飞行控制请求:boxSn -> 多个请求者
|
*/
|
private final ConcurrentHashMap<String, Set<Long>> flyControlRequests = new ConcurrentHashMap<>();
|
|
/**
|
* 载荷控制请求
|
*/
|
private final ConcurrentHashMap<String, Set<Long>> payloadControlRequests = new ConcurrentHashMap<>();
|
|
|
/**
|
* 请求获取 UAV 控制权限
|
*/
|
public boolean requestControl(String boxSn, String type) {
|
UavControlType controlType = UavControlType.fromString(type);
|
Long requester = SecurityUtils.getUserId();
|
return requestSingleControl(boxSn, controlType, requester);
|
}
|
|
/**
|
* 处理单个控制类型的请求
|
*/
|
/**
|
* 处理单个控制类型的请求(支持多请求者)
|
*/
|
private boolean requestSingleControl(String boxSn, UavControlType controlType, Long requester) {
|
|
ConcurrentHashMap<String, Long> controlMap = getControlMap(controlType);
|
ConcurrentHashMap<String, Set<Long>> requestMap = getRequestMap(controlType);
|
|
Long controller = controlMap.get(boxSn);
|
|
// 无人控制 → 直接获取
|
if (controller == null) {
|
controlMap.put(boxSn, requester);
|
uavControlManager.sendControlApproval(requester, boxSn, controlType.getType(), requester);
|
return true;
|
}
|
|
// 已是控制者
|
if (controller.equals(requester)) {
|
throw new ControlException("当前已拥有控制权");
|
}
|
|
int requesterPriority = getUserPriority(requester);
|
int controllerPriority = getUserPriority(controller);
|
|
// 优先级高 → 直接接管
|
if (requesterPriority > controllerPriority) {
|
controlMap.put(boxSn, requester);
|
|
// 通知原控制者被抢占
|
uavControlManager.sendControlTakeover(controller, requester, boxSn, controlType.getType());
|
return true;
|
}
|
|
// ===== 以下是关键改动点 =====
|
|
// 优先级相同或更低 → 加入请求集合(不覆盖)
|
Set<Long> requesters = requestMap.computeIfAbsent(boxSn, k -> ConcurrentHashMap.newKeySet());
|
requesters.add(requester);
|
|
// 通知当前控制者:有新的请求者
|
uavControlManager.sendControlRequest(controller, boxSn, controlType.getType(), requester);
|
|
return false;
|
}
|
|
|
/**
|
* 处理 UAV 控制请求的响应
|
*/
|
public boolean handleControlResponse(String boxSn, boolean approve, String type, Long requester) {
|
UavControlType controlType = UavControlType.fromString(type);
|
Long controller = SecurityUtils.getUserId();
|
return handleSingleControlResponse(boxSn, approve, controlType, controller, requester);
|
}
|
|
|
/**
|
* 处理单个控制类型请求响应
|
*/
|
private boolean handleSingleControlResponse(String boxSn,
|
boolean approve,
|
UavControlType controlType,
|
Long controller,
|
Long requester) {
|
|
ConcurrentHashMap<String, Set<Long>> requestMap = getRequestMap(controlType);
|
Set<Long> requesters = requestMap.get(boxSn);
|
|
if (requesters == null || !requesters.contains(requester)) {
|
throw new ControlException("无控制请求");
|
}
|
|
if (approve) {
|
getControlMap(controlType).put(boxSn, requester);
|
|
// 通知被批准者
|
uavControlManager.sendControlApproval(requester, boxSn, controlType.getType(), controller);
|
|
// 🚨 其他请求者自动拒绝(强烈建议)
|
for (Long other : requesters) {
|
if (!other.equals(requester)) {
|
requesters.remove(requester);
|
uavControlManager.sendControlRejection(other, boxSn, controlType.getType(), controller);
|
}
|
}
|
} else {
|
uavControlManager.sendControlRejection(requester, boxSn, controlType.getType(), controller);
|
}
|
|
requesters.remove(requester);
|
if (requesters.isEmpty()) {
|
requestMap.remove(boxSn);
|
}
|
|
return true;
|
}
|
|
|
/**
|
* 释放 UAV 控制权限
|
*/
|
public boolean releaseControl(String boxSn, String type) {
|
UavControlType controlType = UavControlType.fromString(type);
|
Long controller = SecurityUtils.getUserId();
|
return releaseSingleControl(boxSn, controlType, controller);
|
}
|
|
/**
|
* 释放单个控制类型权限
|
*/
|
private boolean releaseSingleControl(String boxSn, UavControlType controlType, Long controller) {
|
ConcurrentHashMap<String, Long> controlMap = getControlMap(controlType);
|
|
if (!controller.equals(controlMap.get(boxSn))) {
|
throw new ControlException("没有该设备的" + controlType.getType().toUpperCase() + "控制权");
|
}
|
|
controlMap.remove(boxSn);
|
uavControlManager.sendControlRelease(boxSn, controlType.getType(), controller);
|
return true;
|
}
|
|
/**
|
* 释放用户所有控制权限
|
*/
|
public void releaseAllControls(Long userId) {
|
uavFlyControlMap.entrySet().removeIf(entry -> entry.getValue().equals(userId));
|
uavPayloadControlMap.entrySet().removeIf(entry -> entry.getValue().equals(userId));
|
}
|
|
/**
|
* 获取当前某设备的控制用户
|
*/
|
public Long getCurrentController(String boxSn, String type) {
|
UavControlType controlType = UavControlType.fromString(type);
|
return getControlMap(controlType).get(boxSn);
|
}
|
|
public Map<String, Long> getCurrentController(String boxSn) {
|
Map<String, Long> map = new HashMap<>();
|
map.put("flyController", uavFlyControlMap.get(boxSn));
|
map.put("payloadController", uavPayloadControlMap.get(boxSn));
|
return map;
|
}
|
|
/**
|
* 根据控制类型获取对应控制 Map
|
*/
|
private ConcurrentHashMap<String, Long> getControlMap(UavControlType controlType) {
|
switch (controlType) {
|
case FLY:
|
return uavFlyControlMap;
|
case PAYLOAD:
|
return uavPayloadControlMap;
|
default:
|
throw new IllegalArgumentException("不支持的控制类型");
|
}
|
}
|
|
/**
|
* 根据控制类型获取对应请求 Map
|
*/
|
private ConcurrentHashMap<String, Set<Long>> getRequestMap(UavControlType controlType) {
|
switch (controlType) {
|
case FLY:
|
return flyControlRequests;
|
case PAYLOAD:
|
return payloadControlRequests;
|
default:
|
throw new IllegalArgumentException("不支持的控制类型");
|
}
|
}
|
|
|
/**
|
* 获取用户优先级
|
*/
|
private int getUserPriority(Long userId) {
|
return sysUserService.selectUserById(userId).getPriority();
|
}
|
}
|