From 19eea09a791fad0ac9d04086e6eb3fa568382527 Mon Sep 17 00:00:00 2001 From: lilin Date: Thu, 20 Mar 2025 18:35:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=BA=86=E8=BD=A8=E8=BF=B903.20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/ServerSendEventServer.java | 16 + .../controller/TsFilesController.java | 23 ++ .../domain/SimpleNaviData.java | 14 + .../service/ITsFilesService.java | 2 + .../service/impl/TsFilesServiceImpl.java | 276 +++++++++++++++--- .../service/impl/TsNodesServiceImpl.java | 29 +- .../service/impl/FilesServiceImpl.java | 24 ++ .../service/impl/NodesServiceImpl.java | 26 +- .../service/impl/ProjectServiceImpl.java | 42 ++- 9 files changed, 402 insertions(+), 50 deletions(-) create mode 100644 java/src/main/java/com/yfd/platform/modules/experimentalData/domain/SimpleNaviData.java diff --git a/java/src/main/java/com/yfd/platform/component/ServerSendEventServer.java b/java/src/main/java/com/yfd/platform/component/ServerSendEventServer.java index ca1b1fe..d22d2e4 100644 --- a/java/src/main/java/com/yfd/platform/component/ServerSendEventServer.java +++ b/java/src/main/java/com/yfd/platform/component/ServerSendEventServer.java @@ -57,6 +57,20 @@ public class ServerSendEventServer { } } } + public static void sendMessageById(String userId, String message) { + if (sseEmitterMap.containsKey(userId)) { + try { + if(!"0".equals(message)){ + sseEmitterMap.get(userId).send(message); + } + + } catch (IOException e) { + log.error("user id:{}, send message error:{}", userId, + e.getMessage()); + e.printStackTrace(); + } + } + } /** * 给所有用户发消息 @@ -90,6 +104,7 @@ public class ServerSendEventServer { } } + public static void batchSendMessage(String message) { sseEmitterMap.forEach((k, v) -> { try { @@ -102,6 +117,7 @@ public class ServerSendEventServer { }); } + /** * 群发消息 */ diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/controller/TsFilesController.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/controller/TsFilesController.java index f2bead1..20b61b3 100644 --- a/java/src/main/java/com/yfd/platform/modules/experimentalData/controller/TsFilesController.java +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/controller/TsFilesController.java @@ -11,6 +11,7 @@ import com.yfd.platform.modules.experimentalData.service.ITsFilesService; import com.yfd.platform.modules.specialDocument.domain.Files; import com.yfd.platform.modules.specialDocument.service.IFilesService; import io.swagger.annotations.ApiOperation; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -20,6 +21,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; /** *

@@ -394,4 +397,24 @@ public class TsFilesController { } + + @PostMapping("/startSimpleNavi") + public ResponseResult startSimpleNavi(String id,int samTimes,String token) { + try { + // 使用线程池异步执行任务 + CompletableFuture.runAsync(() -> { + try { + tsFilesService.batchSendNaviOutDataJob(id, samTimes, token); + } catch (Exception e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); + + return ResponseResult.success("任务已启动"); + } catch (Exception e) { + return ResponseResult.error("任务启动失败: " + e.getMessage()); + } + + } + } diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/domain/SimpleNaviData.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/domain/SimpleNaviData.java new file mode 100644 index 0000000..74ef268 --- /dev/null +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/domain/SimpleNaviData.java @@ -0,0 +1,14 @@ +package com.yfd.platform.modules.experimentalData.domain; + +import lombok.Data; + +@Data +public class SimpleNaviData { + + private String UtcTime; // UTC_TIME + private String lat; // LAT + private String lon; // LON + private String alt; // ALT + + +} diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/ITsFilesService.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/ITsFilesService.java index 9436b6c..de57932 100644 --- a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/ITsFilesService.java +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/ITsFilesService.java @@ -159,4 +159,6 @@ public interface ITsFilesService extends IService { * @return 文件差异列表 */ TsFiles compareDirectories(List dataset,String nodeId , String taskId); + + void batchSendNaviOutDataJob(String id, int samTimes,String token); } diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java index 6d8fbd4..669f635 100644 --- a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsFilesServiceImpl.java @@ -10,16 +10,21 @@ import java.text.SimpleDateFormat; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import cn.hutool.json.JSONUtil; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectInputStream; import com.amazonaws.util.IOUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.component.ServerSendEventServer; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.modules.experimentalData.domain.*; import com.yfd.platform.modules.experimentalData.mapper.TsFilesMapper; @@ -35,6 +40,9 @@ import com.yfd.platform.modules.storage.model.request.RenameFileRequest; import com.yfd.platform.modules.storage.model.result.FileItemResult; import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService; import com.yfd.platform.system.domain.LoginUser; +import com.yfd.platform.system.domain.SysDictionaryItems; +import com.yfd.platform.system.mapper.SysDictionaryItemsMapper; +import com.yfd.platform.system.service.ISysDictionaryItemsService; import com.yfd.platform.utils.StringUtils; import io.netty.channel.ChannelInboundHandlerAdapter; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; @@ -57,9 +65,6 @@ import java.util.zip.ZipInputStream; import org.apache.commons.codec.binary.Hex; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - /** *

@@ -73,6 +78,7 @@ import java.util.concurrent.ConcurrentMap; public class TsFilesServiceImpl extends ServiceImpl implements ITsFilesService { private static final Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class); + private int time = 1; //试验任务文档表 Mapper @Resource @@ -84,6 +90,12 @@ public class TsFilesServiceImpl extends ServiceImpl impl @Resource private StorageSourceConfigMapper storageSourceConfigMapper; + @Resource + private SysDictionaryItemsMapper sysDictionaryItemsMapper; + // 全局变量,用于存储当前任务的 Future + private Future currentTaskFuture; + + private final ExecutorService executorService = Executors.newSingleThreadExecutor(); /********************************** * 用途说明: 分页查询试验数据管理-文档内容 @@ -101,10 +113,14 @@ public class TsFilesServiceImpl extends ServiceImpl impl ***********************************/ @Override public Page getTsFilesPage(String id, String fileName, String startDate, String endDate, String keywords, String nodeId, String taskId, String fileName1, String childNode, Page page) throws Exception { + //查询字典表获取压缩文件后缀 + QueryWrapper queryWrapperSysDictionary = new QueryWrapper<>(); + queryWrapperSysDictionary.eq("parentcode", "compressType"); + queryWrapperSysDictionary.orderByAsc("orderno"); + List sysDictionaryItems = sysDictionaryItemsMapper.selectList(queryWrapperSysDictionary); QueryWrapper queryWrapper = new QueryWrapper<>(); - // 固定条件过滤 if (StringUtils.isNotBlank(taskId)) queryWrapper.eq("task_id", taskId); if (StringUtils.isNotBlank(nodeId)) queryWrapper.eq("node_id", nodeId); @@ -185,7 +201,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl } tsFiles.setUrl(fileItemResult.getUrl()); //如果是压缩文件 类型就给zip - boolean isValid = hasValidExtension(fileItemResult.getName()); + boolean isValid = hasValidExtension(fileItemResult.getName(), sysDictionaryItems); if (isValid) { tsFiles.setType("ZIP"); } else { @@ -201,12 +217,34 @@ public class TsFilesServiceImpl extends ServiceImpl impl } - public boolean hasValidExtension(String name) { + public boolean hasValidExtension(String name, List sysDictionaryItems) { + // 如果传入的文件名为空,返回 false if (name == null) { - return false; // 如果传入的文件名为空,返回 false + return false; } - // 判断文件名后缀是否是 .zip 或 .tar - return name.endsWith(".zip") || name.endsWith(".tar") || name.endsWith(".rar") || name.endsWith(".xz") || name.endsWith(".tar.gz") || name.endsWith(".gz") || name.endsWith(".bz2"); + // 如果传入的字典表集合为空,返回 false + if (sysDictionaryItems == null || sysDictionaryItems.isEmpty()) { + return false; + } + // 获取文件的扩展名 + String fileExtension = getFileExtension(name); + for (SysDictionaryItems sysDictionaryItems1 : sysDictionaryItems) { + String dictName = "." + sysDictionaryItems1.getDictName(); + if (fileExtension.equalsIgnoreCase(dictName)) { + // 如果文件扩展名与字典表中的扩展名匹配,返回 true + return true; + } + } + // 如果没有匹配的扩展名,返回 false + return false; + } + + // 获取文件扩展名的方法 + private String getFileExtension(String filename) { + if (filename != null && filename.contains(".")) { + return filename.substring(filename.lastIndexOf(".")); + } + return ""; // 如果没有扩展名,返回空字符串 } // 递归获取所有子节点ID(包含隔代子节点) @@ -357,6 +395,12 @@ public class TsFilesServiceImpl extends ServiceImpl impl @Transactional(rollbackFor = Exception.class)// 添加事务注解,遇到异常时回滚 public ResponseResult addTsFile(TsFiles tsFiles) { + // 校验文件名是否包含非法字符 + String fileName = tsFiles.getFileName(); + if (containsInvalidCharacters(fileName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } + //上传人是当前登录人 UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); @@ -402,6 +446,14 @@ public class TsFilesServiceImpl extends ServiceImpl impl } } + // 校验文件名是否包含非法字符 + private boolean containsInvalidCharacters(String fileName) { + // 定义非法字符的正则表达式 + String regex = "[<>:\"/\\\\|?*]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(fileName); + return matcher.find(); + } /********************************** * 用途说明: 修改试验数据管理-文档内容 @@ -412,6 +464,14 @@ public class TsFilesServiceImpl extends ServiceImpl impl @Override @Transactional(rollbackFor = Exception.class)// 添加事务注解,遇到异常时回滚 public ResponseResult updateTsFiles(TsFiles tsFiles) { + + + // 校验文件名是否包含非法字符 + String fileName = tsFiles.getFileName(); + if (containsInvalidCharacters(fileName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } + // 修改之前查询表中的文件名是否修改,如果发生变动先修改 minio 然后再修改表结构 TsFiles filesData = tsFilesMapper.selectById(tsFiles.getId()); @@ -446,13 +506,10 @@ public class TsFilesServiceImpl extends ServiceImpl impl if (flag) { //递归下面所有的文件文件夹 路径都需要修改 List resultList = new ArrayList<>(); - - // 获取父路径(去除自身) - String parentPath = filesData.getWorkPath(); - String[] pathParts = parentPath.split("/"); - int subscript = pathParts.length - 1; - //ID 旧的文件名 新的文件名 - querySubFilesAndUpdatePaths(resultList, tsFiles.getId(), filesData.getFileName(), tsFiles.getFileName(), subscript); + // 获取当前文件夹的完整路径(如 "/147/222/") + String oldFullPath = filesData.getWorkPath() + filesData.getFileName() + "/"; + String newFullPath = filesData.getWorkPath() + tsFiles.getFileName() + "/"; + querySubFilesAndUpdatePaths(resultList, tsFiles.getId(), oldFullPath, newFullPath); // 修改数据库 int valueUpdate = tsFilesMapper.updateById(tsFiles); if (valueUpdate == 1) { @@ -516,7 +573,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl } - private void querySubFilesAndUpdatePaths(List resultList, String id, String oldName, String newName, int subscript) { + private void querySubFilesAndUpdatePaths(List resultList, String id, String oldName, String newName) { // 构造 QueryWrapper 查询当前文件夹下的文件 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("parent_id", id); @@ -532,37 +589,20 @@ public class TsFilesServiceImpl extends ServiceImpl impl // 遍历每个子项,更新路径并递归查询其子项 for (TsFiles subFile : subFiles) { - // 获取原始路径 + String oldWorkPath = subFile.getWorkPath(); - // 替换路径中的 oldName 为 newName,仅替换路径数组中指定下标的部分 - String newWorkPath = updatePathAtSubscript(oldWorkPath, oldName, newName, subscript); + // 使用正则表达式替换目标文件夹名称 + String newWorkPath = oldWorkPath.replaceAll(oldName, newName); // 更新数据库中的路径 subFile.setWorkPath(newWorkPath); tsFilesMapper.updateById(subFile); // 递归查询每个子项的子文件 if ("FOLDER".equals(subFile.getIsFile())) { - querySubFilesAndUpdatePaths(resultList, subFile.getId(), oldName, newName, subscript); + querySubFilesAndUpdatePaths(resultList, subFile.getId(), oldName, newName); } - querySubFilesAndUpdatePaths(resultList, subFile.getId(), oldName, newName, subscript); } } - // 辅助方法,更新路径中特定下标的部分 - private String updatePathAtSubscript(String oldPath, String oldName, String newName, int subscript) { - // 过滤空值 - List pathParts = Arrays.stream(oldPath.split("/")) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - - // 确保路径数组下标有效 - if (pathParts.size() > subscript) { - pathParts.set(subscript, pathParts.get(subscript).replace(oldName, newName)); - } - - // 拼接成新的路径 - return "/" + String.join("/", pathParts) + "/"; - } - /********************************** * 用途说明: 批量删除试验数据管理-文档内容 * 参数说明 id 文档内容ID @@ -889,7 +929,15 @@ public class TsFilesServiceImpl extends ServiceImpl impl tsFiles.setNodeId(filesList.get(0).getNodeId()); tsFiles.setWorkPath(compressedPath); tsFiles.setIsFile("FILE"); - tsFiles.setFileSize(String.valueOf(zipFilePath.toFile().length())); + + // 获取文件大小(字节) + long fileSizeInBytes = zipFilePath.toFile().length(); + // 转换为 MB 并保留两位小数 + double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0); + String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数 + // 设置文件大小 + tsFiles.setFileSize(fileSizeFormatted); + //tsFiles.setFileSize(String.valueOf(zipFilePath.toFile().length())); tsFiles.setParentId(parentId); tsFiles.setBackupPath(""); tsFiles.setKeywords(""); @@ -1128,6 +1176,12 @@ public class TsFilesServiceImpl extends ServiceImpl impl if (file.isDirectory()) { continue; } else { + // 获取文件大小(字节) + long fileSizeInBytes = file.length(); + // 转换为 MB 并保留两位小数 + double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0); + String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数 + TsFiles fileRecord = createFileRecord( file.getName(), parentId, @@ -1135,7 +1189,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl zipFileRecord.getTaskId(), zipFileRecord.getNodeId(), zipFileRecord.getUploader(), - file.length() + fileSizeFormatted ); } } @@ -1170,7 +1224,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl * 创建文件记录 */ private TsFiles createFileRecord(String fileName, String parentId, String workPath, - String taskId, String nodeId, String uploader, long fileSize) { + String taskId, String nodeId, String uploader, String fileSize) { QueryWrapper query = new QueryWrapper() .eq("node_id", nodeId) @@ -1190,7 +1244,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl fileRecord.setFileName(fileName); fileRecord.setWorkPath(workPath); fileRecord.setIsFile("FILE"); - fileRecord.setFileSize(String.valueOf(fileSize)); + fileRecord.setFileSize(fileSize); fileRecord.setUploadTime(new Timestamp(System.currentTimeMillis())); operateTsfeiles(fileRecord); // 插入或更新记录 return fileRecord; @@ -1254,6 +1308,12 @@ public class TsFilesServiceImpl extends ServiceImpl impl uploader ); } else { + + // 获取文件大小(字节) + long fileSizeInBytes = child.length(); + // 转换为 MB 并保留两位小数 + double fileSizeInMB = fileSizeInBytes / (1024.0 * 1024.0); + String fileSizeFormatted = String.format("%.2f", fileSizeInMB); // 保留两位小数 // 处理文件(示例:1.txt) TsFiles fileRecord = new TsFiles(); fileRecord.setNodeId(nodeId); @@ -1263,7 +1323,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl fileRecord.setWorkPath(parentWorkPath); // /333/222/ fileRecord.setIsFile("FILE"); fileRecord.setUploadTime(new Timestamp(System.currentTimeMillis())); - fileRecord.setFileSize(String.valueOf(child.length())); + fileRecord.setFileSize(fileSizeFormatted); operateTsfeiles(fileRecord); // // tsFilesMapper.insert(fileRecord); @@ -1537,6 +1597,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl return tsFiles; } + // 辅助方法:获取存储配置 private StorageSourceConfig getStorageConfig(String name) { return storageSourceConfigMapper.selectOne( @@ -1698,6 +1759,8 @@ public class TsFilesServiceImpl extends ServiceImpl impl // 辅助方法:丰富文件元数据 private FileItemResult enrichFileMetadata(FileItemResult file, String pathType) { String aaaa = normalizePath(file.getPath()); + String bbbb = pathType; + System.out.print("aaaa"+ file.getName()); TsFiles dbRecord = tsFilesMapper.selectOne( new QueryWrapper() .eq("file_name", file.getName()) @@ -3164,6 +3227,13 @@ public class TsFilesServiceImpl extends ServiceImpl impl * @return 转换后的 DTO */ private TreeDTO convertToDTO(TsFiles node, boolean isLocal) { + //查询字典表获取压缩文件后缀 + QueryWrapper queryWrapperSysDictionary = new QueryWrapper<>(); + queryWrapperSysDictionary.eq("parentcode", "compressType"); + queryWrapperSysDictionary.orderByAsc("orderno"); + List sysDictionaryItems = sysDictionaryItemsMapper.selectList(queryWrapperSysDictionary); + + TreeDTO dto = new TreeDTO(); // 复制公共字段 dto.setId(node.getId()); @@ -3196,7 +3266,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl if (fileItemResult != null || fileItemResult.getName() != null) { dto.setUrl(fileItemResult.getUrl()); //如果是压缩文件 类型就给zip - boolean isValid = hasValidExtension(fileItemResult.getName()); + boolean isValid = hasValidExtension(fileItemResult.getName(), sysDictionaryItems); if (isValid) { dto.setType("ZIP"); } else { @@ -3221,7 +3291,7 @@ public class TsFilesServiceImpl extends ServiceImpl impl if (fileItemResult != null || fileItemResult.getName() != null) { dto.setUrl(fileItemResult.getUrl()); //如果是压缩文件 类型就给zip - boolean isValid = hasValidExtension(fileItemResult.getName()); + boolean isValid = hasValidExtension(fileItemResult.getName(), sysDictionaryItems); if (isValid) { dto.setType("ZIP"); } else { @@ -3235,4 +3305,120 @@ public class TsFilesServiceImpl extends ServiceImpl impl return dto; } + + /*******************************************读取文件内容经纬度**************************************************************/ + + @Override + public void batchSendNaviOutDataJob(String id, int samTimes, String token) { + if (currentTaskFuture != null && !currentTaskFuture.isDone()) { + currentTaskFuture.cancel(true); // 中断之前的任务 + } + currentTaskFuture = executorService.submit(() -> { + TsFiles tsFiles = tsFilesMapper.selectById(id); + StorageSourceConfig config = storageSourceConfigMapper.selectOne( + new QueryWrapper().eq("name", "filePath")); + Path filePath = Paths.get(config.getValue() + tsFiles.getWorkPath() + tsFiles.getFileName()); + + try (BufferedReader reader = new BufferedReader(new FileReader(filePath.toFile()))) { + reader.readLine(); // 跳过标题行 + + // 不管 samTimes 如何,先读取第一行数据 + String firstLine = reader.readLine(); + if (firstLine != null) { + firstLine = firstLine.trim(); + String[] values = firstLine.split("\t"); + if (values.length >= 40) { + // 发送第一行数据 + sendData(token, values, 1); + } else { + System.err.println("忽略不完整行: " + firstLine); + } + } + + int step = samTimes * 200; // 计算行号间隔 + int lineCount = 1; // 从第一行开始 + + while (!Thread.currentThread().isInterrupted()) { + lineCount += step; // 直接跳到下一个需要读取的行 + String line = null; + + // 读取指定行 + for (int i = 0; i < step; i++) { + line = reader.readLine(); + if (line == null) break; // 文件结束 + } + + if (line == null) break; // 文件结束 + + line = line.trim(); + String[] values = line.split("\t"); + if (values.length < 40) { + LOGGER.info("忽略不完整行: " + line); + continue; + } + + // 发送数据 + sendData(token, values, lineCount); + + // 固定休眠 3 秒 + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + // 如果休眠期间被中断,则退出循环 + Thread.currentThread().interrupt(); + break; + } + } + + // 发送完成信号(如果需要) + if (!Thread.currentThread().isInterrupted()) { + // ServerSendEventServer.sendMessage(token, "COMPLETED"); + } + + } catch (Exception e) { + // 捕获异常并记录日志 + LOGGER.error("任务执行失败: " + e.getMessage()); + e.printStackTrace(); + } + }); + } + + + // 封装发送数据的逻辑 + private void sendData(String token, String[] values, int lineCount) { + if (Thread.currentThread().isInterrupted()) { + return; // 如果线程已被中断,则直接返回 + } + + try { + SimpleNaviData data = parseLine(values); + String jsonData = JSONUtil.toJsonStr(data); // 假设 JSONUtil.toJsonStr 不会抛出 IOException + ServerSendEventServer.sendMessageById(token, jsonData); // 假设 sendMessage 不会抛出 IOException + LOGGER.info("Line " + lineCount + " sent at: " + System.currentTimeMillis()); + } catch (Exception e) { + // 捕获所有可能的异常 + LOGGER.error("发送数据失败: " + e.getMessage()); + if (e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); // 重新设置中断状态 + } + } + } + + // 辅助方法:解析行数据 + private SimpleNaviData parseLine(String[] values) { + SimpleNaviData data = new SimpleNaviData(); + data.setUtcTime(getValueSafely(values, 8, "0.0")); // UTC_TIME(索引8) + data.setLat(getValueSafely(values, 17, "0.0")); // LAT(索引17) + data.setLon(getValueSafely(values, 18, "0.0")); // LON(索引18) + data.setAlt(getValueSafely(values, 19, "0.0")); // ALT(索引19) + return data; + } + + // 安全获取数组值的方法 + private String getValueSafely(String[] values, int index, String defaultValue) { + return (index < values.length) ? values[index] : defaultValue; + } } + + + diff --git a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java index 3dc7591..bf24812 100644 --- a/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/experimentalData/service/impl/TsNodesServiceImpl.java @@ -35,6 +35,8 @@ import javax.annotation.Resource; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -244,6 +246,12 @@ public class TsNodesServiceImpl extends ServiceImpl impl @Transactional(rollbackFor = Exception.class) // 添加事务注解,遇到异常时回滚 public ResponseResult addTsNodes(TsNodes tsnodes) { + + // 校验文件名是否包含非法字符 + String nodeName = tsnodes.getNodeName(); + if (containsInvalidCharacters(nodeName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } // 差不多的流程 就是提出来 然后判断 如果两个 中有一个是true //获取当前登录用户 UsernamePasswordAuthenticationToken authentication = @@ -283,6 +291,17 @@ public class TsNodesServiceImpl extends ServiceImpl impl } + + // 校验文件名是否包含非法字符 + private boolean containsInvalidCharacters(String nodeName) { + // 定义非法字符的正则表达式 + String regex = "[<>:\"/\\\\|?*]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(nodeName); + return matcher.find(); + } + + /********************************** * 用途说明: 修改试验任务节点 * 参数说明 tsnodes 试验任务节点信息 @@ -290,10 +309,16 @@ public class TsNodesServiceImpl extends ServiceImpl impl ***********************************/ @Override public ResponseResult updateTsNodes(TsNodes tsnodes) { + + // 校验文件名是否包含非法字符 + String nodeName = tsnodes.getNodeName(); + if (containsInvalidCharacters(nodeName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } + //查询没改之前的节点名称 TsNodes nodesold = tsNodesMapper.selectById(tsnodes.getNodeId()); - //新的节点名称 - String nodeName = tsnodes.getNodeName(); + //老的节点名称 String nodeNameOld = null; if (ObjUtil.isNotEmpty(nodesold)) { diff --git a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/FilesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/FilesServiceImpl.java index 58009a3..aee4839 100644 --- a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/FilesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/FilesServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.config.ResponseResult; import com.yfd.platform.exception.file.InvalidStorageSourceException; import com.yfd.platform.modules.config.model.request.FileListRequest; import com.yfd.platform.modules.specialDocument.domain.Files; @@ -41,6 +42,8 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** *

@@ -187,6 +190,13 @@ public class FilesServiceImpl extends ServiceImpl implements @Override public Boolean addFiles(Files files) { Boolean value = false; + // 校验文件名是否包含非法字符 + String fileName = files.getFileName(); + if (containsInvalidCharacters(fileName)) { + return value; + } + + // String[] splitIds = ids.split(","); BigDecimal List names = Arrays.asList(files.getFileName().split(",")); List sizes = Arrays.asList(files.getFileSize().split(",")); @@ -253,6 +263,12 @@ public class FilesServiceImpl extends ServiceImpl implements @Override @Transactional(rollbackFor = Exception.class)// 添加事务注解,遇到异常时回滚 public boolean updateFiles(Files files) { + // 校验文件名是否包含非法字符 + String fileName = files.getFileName(); + if (containsInvalidCharacters(fileName)) { + return false; + } + // 修改之前查询表中的文件名是否修改,如果发生变动先修改 minio 然后再修改表结构 Files filesData = filesMapper.selectById(files.getId()); @@ -282,6 +298,14 @@ public class FilesServiceImpl extends ServiceImpl implements } } + // 校验文件名是否包含非法字符 + private boolean containsInvalidCharacters(String fileName) { + // 定义非法字符的正则表达式 + String regex = "[<>:\"/\\\\|?*]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(fileName); + return matcher.find(); + } /********************************** * 用途说明: 根据ID删除专项文档管理-文档内容 diff --git a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java index e7456ad..733c652 100644 --- a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/NodesServiceImpl.java @@ -36,6 +36,8 @@ import javax.annotation.Resource; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** *

@@ -259,6 +261,12 @@ public class NodesServiceImpl extends ServiceImpl implements @Transactional(rollbackFor = Exception.class) // 添加事务注解,遇到异常时回滚 public ResponseResult addNodes(Nodes nodes) { + // 校验文件名是否包含非法字符 + String nodeName = nodes.getNodeName(); + if (containsInvalidCharacters(nodeName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } + //获取当前登录用户 UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); @@ -333,10 +341,15 @@ public class NodesServiceImpl extends ServiceImpl implements @Override @Transactional(rollbackFor = Exception.class) // 添加事务注解,遇到异常时回滚 public ResponseResult updateNodes(Nodes nodes) { - //查询没改之前的节点名称 - Nodes nodesold = nodesMapper.selectById(nodes.getId()); + //新的节点名称 String nodeName = nodes.getNodeName(); + if (containsInvalidCharacters(nodeName)) { + return ResponseResult.error("文件名包含非法字符(<>:\"/\\|?*)!"); + } + + //查询没改之前的节点名称 + Nodes nodesold = nodesMapper.selectById(nodes.getId()); //老的节点名称 String nodeNameOld = null; if (ObjUtil.isNotEmpty(nodesold)) { @@ -405,6 +418,15 @@ public class NodesServiceImpl extends ServiceImpl implements } } + // 校验文件名是否包含非法字符 + private boolean containsInvalidCharacters(String nodeName) { + // 定义非法字符的正则表达式 + String regex = "[<>:\"/\\\\|?*]"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(nodeName); + return matcher.find(); + } + /** * 更新文件路径中的节点名称 */ diff --git a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/ProjectServiceImpl.java b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/ProjectServiceImpl.java index 7faa8bd..77e1ebf 100644 --- a/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/ProjectServiceImpl.java +++ b/java/src/main/java/com/yfd/platform/modules/specialDocument/service/impl/ProjectServiceImpl.java @@ -7,6 +7,7 @@ import com.yfd.platform.modules.specialDocument.domain.Project; import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper; import com.yfd.platform.modules.specialDocument.service.IProjectService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.system.domain.SysDictionaryItems; import com.yfd.platform.system.mapper.SysDictionaryItemsMapper; import com.yfd.platform.utils.StringUtils; import org.springframework.stereotype.Service; @@ -31,6 +32,11 @@ public class ProjectServiceImpl extends ServiceImpl impl @Resource private ProjectMapper projectMapper; + + //字典表Mapper + @Resource + private SysDictionaryItemsMapper sysDictionaryItemsMapper; + /********************************** * 用途说明: 分页查询专项文档管理-项目管理 * 参数说明 @@ -42,6 +48,7 @@ public class ProjectServiceImpl extends ServiceImpl impl ***********************************/ @Override public Page getSdProjectPage(String projectCode, String projectType, String projectName, Page page) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); //如果项目编号 projectCode 不为空 if (StringUtils.isNotEmpty(projectCode)) { @@ -49,7 +56,18 @@ public class ProjectServiceImpl extends ServiceImpl impl } //如果项目类型 projectType 不为空 if (StringUtils.isNotEmpty(projectType)) { - queryWrapper.like(Project::getProjectType, projectType); + + //查询字典表获取项目类型对应数据字典 + QueryWrapper queryWrapperSysDictionary = new QueryWrapper<>(); + queryWrapperSysDictionary.eq("parentcode", "zxxmlx"); + queryWrapperSysDictionary.eq("itemcode", projectType); + queryWrapperSysDictionary.orderByAsc("orderno"); + SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary); + if(sysDictionaryItems != null){ + queryWrapper.like(Project::getProjectType, sysDictionaryItems.getDictName()); + }else { + queryWrapper.like(Project::getProjectType, projectType); + } } //如果项目名称 projectName 不为空 if (StringUtils.isNotEmpty(projectName)) { @@ -70,6 +88,17 @@ public class ProjectServiceImpl extends ServiceImpl impl ***********************************/ @Override public Boolean addSdproject(Project project) { + //查询字典表获取项目类型对应数据字典 + QueryWrapper queryWrapperSysDictionary = new QueryWrapper<>(); + queryWrapperSysDictionary.eq("parentcode", "zxxmlx"); + queryWrapperSysDictionary.eq("itemcode", project.getProjectType()); + queryWrapperSysDictionary.orderByAsc("orderno"); + SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary); + if(sysDictionaryItems != null){ + project.setProjectType(sysDictionaryItems.getDictName()); + } + + //TODO 01.21沟通以后说是先不用管重复校验问题 // //通过项目名称 项目编号查询 查看是否存在 // QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -104,6 +133,17 @@ public class ProjectServiceImpl extends ServiceImpl impl ***********************************/ @Override public boolean updateSdproject(Project project) { + //查询字典表获取项目类型对应数据字典 + QueryWrapper queryWrapperSysDictionary = new QueryWrapper<>(); + queryWrapperSysDictionary.eq("parentcode", "zxxmlx"); + queryWrapperSysDictionary.eq("itemcode", project.getProjectType()); + queryWrapperSysDictionary.orderByAsc("orderno"); + SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary); + if(sysDictionaryItems != null){ + project.setProjectType(sysDictionaryItems.getDictName()); + } + + int valueUpdate = projectMapper.updateById(project); if (valueUpdate == 1) { return true;