package com.ard.work.service.impl; import com.alibaba.fastjson2.JSONObject; import com.ard.common.exception.ServiceException; import com.ard.common.utils.DateUtils; import com.ard.common.utils.uuid.IdUtils; import com.ard.system.authorize.service.AuthorizeService; import com.ard.work.domain.entity.ArdDroneInfo; import com.ard.work.domain.receiver.BoxInfoReceiver; import com.ard.work.mapper.ArdDroneInfoMapper; import com.ard.work.service.IArdDroneInfoService; import com.ard.work.service.ITyService; import com.ard.work.util.UtilMethod; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * 无人机盒子Service业务层处理 * * @author ard * @date 2025-03-04 */ @Slf4j @Service public class ArdDroneInfoServiceImpl implements IArdDroneInfoService { @Resource private ArdDroneInfoMapper ArdDroneInfoMapper; @Resource private ITyService tyService; @Resource private AuthorizeService authorizeService; /** * 查询无人机盒子 * * @param id 无人机盒子主键 * @return 无人机盒子 */ @Override public ArdDroneInfo selectArdDroneById(String id) { return ArdDroneInfoMapper.selectArdDroneById(id); } /** * 查询无人机盒子 * * @param boxSn 盒子编码 * @return 无人机盒子 */ @Override public ArdDroneInfo selectArdDroneByboxSn(String boxSn) { return ArdDroneInfoMapper.selectArdDroneByBoxSn(boxSn); } /** * 查询无人机盒子列表 * * @param ArdDroneInfo 无人机盒子 * @return 无人机盒子 */ @Override public List selectArdDroneList(ArdDroneInfo ArdDroneInfo) { return ArdDroneInfoMapper.selectArdDroneList(ArdDroneInfo); } /** * 新增无人机盒子 * * @param ardDroneInfo 无人机盒子 * @return 结果 */ @Override public int insertArdDrone(ArdDroneInfo ardDroneInfo) { ardDroneInfo.setId(IdUtils.fastUUID()); ardDroneInfo.setCreateTime(DateUtils.getNowDate()); return ArdDroneInfoMapper.insertArdDrone(ardDroneInfo); } /** * 修改无人机盒子 * * @param ArdDroneInfo 无人机盒子 * @return 结果 */ @Override public int updateArdDrone(ArdDroneInfo ArdDroneInfo) { ArdDroneInfo.setUpdateTime(DateUtils.getNowDate()); return ArdDroneInfoMapper.updateArdDrone(ArdDroneInfo); } /** * 批量删除无人机盒子 * * @param ids 需要删除的无人机盒子主键 * @return 结果 */ @Override public int deleteArdDroneByIds(String[] ids) { return ArdDroneInfoMapper.deleteArdDroneByIds(ids); } /** * 删除无人机盒子信息 * * @param id 无人机盒子主键 * @return 结果 */ @Override public int deleteArdDroneById(String id) { return ArdDroneInfoMapper.deleteArdDroneById(id); } /** * 批量新增无人机盒子 * * @param boxSn 盒子编码数组 * @param deptId 部门ID * @return 成功插入的记录数 */ @Override public int insertArdDroneLs(String[] boxSn, Long deptId) { // 参数校验 if (boxSn == null || boxSn.length == 0) { log.warn("传入的盒子编码为空"); return 1; } if (deptId == null) { throw new IllegalArgumentException("部门ID不能为空"); } try { // 1. 检查已存在的无人机盒子 List existingDrones = getExistingDrones(boxSn); // 2. 授权数量验证 validateAuthorization(existingDrones.size(), boxSn.length); // 3. 获取并组装新的无人机信息 List newDrones = assembleNewDrones(boxSn, deptId); // 4. 批量插入 return batchInsertDrones(newDrones); } catch (Exception e) { log.error("批量新增无人机盒子失败, boxSn: {}, deptId: {}", Arrays.toString(boxSn), deptId, e); throw new ServiceException("批量新增无人机盒子失败: " + e.getMessage()); } } /** * 修改无人机状态 */ @Override public int updateDroneStatus(String serverId, String status) { return ArdDroneInfoMapper.updateDroneStatus(serverId, status); } /** * 获取已存在的无人机信息 */ private List getExistingDrones(String[] boxSn) { return Arrays.stream(boxSn) .map(ArdDroneInfoMapper::selectArdDroneByBoxSn) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** * 验证授权数量 */ private void validateAuthorization(int existingCount, int newCount) { int totalCount = existingCount + newCount; JSONObject authInfo = authorizeService.getAuthorizationInfo(); String authType = authInfo.getString("Type"); switch (authType) { case "normal": int allowedDroneNum = authInfo.getIntValue("droneNum"); if (totalCount > allowedDroneNum) { throw new RuntimeException(String.format( "授权数量%d,当前操作将导致总数达到%d,超过授权限制", allowedDroneNum, totalCount)); } break; case "expired": throw new RuntimeException("授权文件已过期"); case "mismatch": throw new RuntimeException("授权文件不匹配"); default: throw new RuntimeException("未知的授权类型: " + authType); } } /** * 组装新的无人机信息 */ private List assembleNewDrones(String[] boxSn, Long deptId) { List allBoxes = tyService.getBoxList(); Set targetBoxSnSet = new HashSet<>(Arrays.asList(boxSn)); return allBoxes.stream() .filter(box -> targetBoxSnSet.contains(box.getBoxSn())) .map(box -> createDroneInfo(box, deptId)) .collect(Collectors.toList()); } /** * 创建无人机信息对象 */ private ArdDroneInfo createDroneInfo(BoxInfoReceiver box, Long deptId) { ArdDroneInfo drone = new ArdDroneInfo(); drone.setId(IdUtils.simpleUUID()); drone.setBoxSn(box.getBoxSn()); drone.setBoxName(box.getBoxName()); drone.setBoxAliasName(box.getBoxName()); drone.setStartTime(new Date()); drone.setOnLine(box.getOnLine()); drone.setVideoServer(box.getVideoServer()); drone.setVideoPort(box.getVideoPort()); drone.setLastTaskId(box.getLastTaskId()); drone.setDeptId(deptId); // 设置创建信息和更新信息 setCreateAndUpdateInfo(drone); return drone; } /** * 设置创建和更新信息 */ private void setCreateAndUpdateInfo(ArdDroneInfo drone) { Date currentTime = new Date(); drone.setCreateTime(currentTime); drone.setUpdateTime(currentTime); } /** * 批量插入无人机信息 */ private int batchInsertDrones(List drones) { if (drones.isEmpty()) { return 0; } return ArdDroneInfoMapper.insertArdDroneLs(drones); } /** * 同步盒子属性 * * @return 结果 */ @Scheduled(fixedRate = 1000 * 10) public void syncBoxInfo() { List ArdDroneeListEntity = selectArdDroneList(new ArdDroneInfo()); // 将本地列表转换为Map,方便快速查找 Map localArdDroneMap = ArdDroneeListEntity.stream() .collect(Collectors.toMap(ArdDroneInfo::getBoxSn, drone -> drone)); //遍历接口最新获取的无人机盒子信息 tyService.getBoxList().forEach(remoteArdDrone -> { ArdDroneInfo localArdDroneInfo = localArdDroneMap.get(remoteArdDrone.getBoxSn()); if (localArdDroneInfo != null) { if (!localArdDroneInfo.isSameAs(remoteArdDrone)) { // 修改无人机(只更新变化的属性) updateChangedAttributes(localArdDroneInfo, remoteArdDrone); updateArdDrone(localArdDroneInfo); } } }); } // 更新变化的属性 private void updateChangedAttributes(ArdDroneInfo localBoxInfo, BoxInfoReceiver remoteArdDrone) { if (!Objects.equals(localBoxInfo.getBoxName(), remoteArdDrone.getBoxName())) { localBoxInfo.setBoxName(remoteArdDrone.getBoxName()); } if (!Objects.equals(localBoxInfo.getBoxVersion(), remoteArdDrone.getBoxVersion())) { localBoxInfo.setBoxVersion(remoteArdDrone.getBoxVersion()); } if (!Objects.equals(localBoxInfo.getLastTaskId(), remoteArdDrone.getLastTaskId())) { localBoxInfo.setLastTaskId(remoteArdDrone.getLastTaskId()); } if (!Objects.equals(localBoxInfo.getOnLine(), remoteArdDrone.getOnLine())) { localBoxInfo.setOnLine(remoteArdDrone.getOnLine()); } // 更新其他属性 } }