diff --git a/pom.xml b/pom.xml
index fb40057..7c96930 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,13 @@
3.5.2
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.34.0
+
+
org.aspectj
aspectjweaver
diff --git a/src/main/java/org/nl/apt15e/Apt15EApplication.java b/src/main/java/org/nl/apt15e/Apt15EApplication.java
index cf11d84..0e270ba 100644
--- a/src/main/java/org/nl/apt15e/Apt15EApplication.java
+++ b/src/main/java/org/nl/apt15e/Apt15EApplication.java
@@ -4,6 +4,7 @@ import org.mybatis.spring.annotation.MapperScan;
import org.nl.apt15e.config.SpringContextHolder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
diff --git a/src/main/java/org/nl/apt15e/apt/anomalyInfo/controller/AnomalyInfoController.java b/src/main/java/org/nl/apt15e/apt/anomalyInfo/controller/AnomalyInfoController.java
index 0d531d4..2d27091 100644
--- a/src/main/java/org/nl/apt15e/apt/anomalyInfo/controller/AnomalyInfoController.java
+++ b/src/main/java/org/nl/apt15e/apt/anomalyInfo/controller/AnomalyInfoController.java
@@ -13,6 +13,7 @@ import org.nl.apt15e.common.excel.ErrorHandlingListener;
import org.nl.apt15e.common.excel.ErrorInfoListener;
import org.nl.apt15e.config.file.FileProperties;
import org.nl.apt15e.config.language.LangProcess;
+import org.nl.apt15e.util.FileConstant;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@@ -104,7 +105,7 @@ public class AnomalyInfoController {
try {
// 创建上传目录
- File uploadDir = new File(properties.getPath().getPath());
+ File uploadDir = new File(FileConstant.ERROR_IMAGE_PATH);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
diff --git a/src/main/java/org/nl/apt15e/apt/map/service/impl/MapInfoServiceImpl.java b/src/main/java/org/nl/apt15e/apt/map/service/impl/MapInfoServiceImpl.java
index 5396f79..7e96a1d 100644
--- a/src/main/java/org/nl/apt15e/apt/map/service/impl/MapInfoServiceImpl.java
+++ b/src/main/java/org/nl/apt15e/apt/map/service/impl/MapInfoServiceImpl.java
@@ -68,7 +68,7 @@ public class MapInfoServiceImpl extends ServiceImpl impl
}
} catch (Exception e) {
log.info("同步地图失败:{}",e.getMessage());
- throw new BadRequestException(LangProcess.msg("failed"));
+ throw new BadRequestException(LangProcess.msg("failed")+":"+e.getMessage());
}
}
}
diff --git a/src/main/java/org/nl/apt15e/apt/route/dao/RouteInfo.java b/src/main/java/org/nl/apt15e/apt/route/dao/RouteInfo.java
index f313a73..2f90768 100644
--- a/src/main/java/org/nl/apt15e/apt/route/dao/RouteInfo.java
+++ b/src/main/java/org/nl/apt15e/apt/route/dao/RouteInfo.java
@@ -49,7 +49,7 @@ public class RouteInfo {
private Double end_y;
/**
- * 导航模式 前进模式, 后退模式 ,无头模式
+ * 导航模式 前进模式, 后退模式 ,双向模式
*/
private String navigation_mode;
diff --git a/src/main/java/org/nl/apt15e/apt/teaching/service/impl/TeachingServiceImpl.java b/src/main/java/org/nl/apt15e/apt/teaching/service/impl/TeachingServiceImpl.java
index 7f717d8..0b992c7 100644
--- a/src/main/java/org/nl/apt15e/apt/teaching/service/impl/TeachingServiceImpl.java
+++ b/src/main/java/org/nl/apt15e/apt/teaching/service/impl/TeachingServiceImpl.java
@@ -301,7 +301,7 @@ public class TeachingServiceImpl implements TeachingService {
try {
response = HttpRequest.post(URLConstant.RCS_IP_PORT+"/map/uploadFile")
.setConnectionTimeout(3000)
- .setReadTimeout(3000)
+ .setReadTimeout(30000)
.header("token", "admin123")
.header("name", "lx-script")
.header("Content-Type", "multipart/form-data;charset=UTF-8")
diff --git a/src/main/java/org/nl/apt15e/apt/vehicle/ProcessZip.java b/src/main/java/org/nl/apt15e/apt/vehicle/ProcessZip.java
index 51c66f6..111c682 100644
--- a/src/main/java/org/nl/apt15e/apt/vehicle/ProcessZip.java
+++ b/src/main/java/org/nl/apt15e/apt/vehicle/ProcessZip.java
@@ -19,6 +19,7 @@ import org.nl.apt15e.apt.teaching.service.impl.TeachingServiceImpl;
import org.nl.apt15e.common.BadRequestException;
import org.nl.apt15e.config.file.FileProperties;
import org.nl.apt15e.config.language.LangProcess;
+import org.nl.apt15e.util.FileConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -35,10 +36,8 @@ import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.*;
import java.util.List;
-import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -69,6 +68,8 @@ public class ProcessZip {
private static final String PGM_MAGIC_NUMBER = "P5";
+ private List routeInfoList = new ArrayList<>();
+
@Transactional(rollbackFor = Exception.class)
public void processZipResponse(byte[] zipBytes) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(zipBytes);
@@ -97,6 +98,8 @@ public class ProcessZip {
String line;
int lineNumber = 0;
+ // 清除路径信息
+ routeInfoList.clear();
while ((line = reader.readLine()) != null) {
lineNumber++;
// 5. 处理每一行数据
@@ -105,6 +108,12 @@ public class ProcessZip {
if (lineNumber == 0) {
throw new BadRequestException(LangProcess.msg("error_map_pack_isNull"));
}
+ // 批量保存路径信息
+ if (ObjectUtil.isNotEmpty(routeInfoList)){
+ routeInfoList = mergeBidirectionalRoutes(routeInfoList);
+ routeInfoService.saveBatch(routeInfoList);
+ }
+
}
// 点云图 .pgm 文件转换 .png
if (entryName.toLowerCase().endsWith(".pgm")) {
@@ -325,7 +334,8 @@ public class ProcessZip {
routeInfo.setEnd_y(Double.valueOf(processData[7]));
routeInfo.setNavigation_mode(processData[16].replaceAll("^\"|\"$", ""));
routeInfo.setRoute_type(processData[17].replaceAll("^\"|\"$", ""));
- routeInfoService.save(routeInfo);
+ routeInfoList.add(routeInfo);
+// routeInfoService.save(routeInfo);
System.out.printf("行号 %d - 有效数据: %s%n", lineNumber, routeInfo);
}
@@ -457,7 +467,7 @@ public class ProcessZip {
}
/**
- * 判断是否是图片文件
+ * 判断是否是图片文件或者视频文件
* @param filename
* @return
*/
@@ -468,7 +478,8 @@ public class ProcessZip {
lowerCaseFilename.endsWith(".png") ||
lowerCaseFilename.endsWith(".gif") ||
lowerCaseFilename.endsWith(".bmp") ||
- lowerCaseFilename.endsWith(".webp");
+ lowerCaseFilename.endsWith(".webp")||
+ lowerCaseFilename.endsWith(".mp4");
}
/**
@@ -477,7 +488,7 @@ public class ProcessZip {
* @return
*/
private boolean isFileExists(String filename) {
- File targetFile = new File(properties.getPath().getPath() + filename);
+ File targetFile = new File(FileConstant.ERROR_IMAGE_PATH+ "/" + filename);
return targetFile.exists();
}
@@ -489,7 +500,7 @@ public class ProcessZip {
*/
private boolean saveImageFile(InputStream inputStream, String filename) {
try {
- File outputFile = new File(properties.getPath().getPath() + filename);
+ File outputFile = new File(FileConstant.ERROR_IMAGE_PATH + "/" + filename);
// 确保目录存在
File parentDir = outputFile.getParentFile();
@@ -504,4 +515,47 @@ public class ProcessZip {
return false;
}
}
+
+ public static List mergeBidirectionalRoutes(List originalData) {
+ List mergedData = new ArrayList<>();
+ Map routeMap = new HashMap<>();
+ Set processedIds = new HashSet<>();
+
+ // 第一次遍历:构建快速查找映射
+ for (RouteInfo route : originalData) {
+ String key = route.getStart_id() + "-" + route.getEnd_id();
+ routeMap.put(key, route);
+ }
+
+ // 第二次遍历:查找并合并双向路径
+ for (RouteInfo route : originalData) {
+ if (processedIds.contains(route.getRoute_id())) {
+ continue;
+ }
+
+// String forwardKey = route.getStart_id() + "-" + route.getEnd_id();
+ String reverseKey = route.getEnd_id() + "-" + route.getStart_id();
+
+ // 检查是否存在精确反向路径
+ if (routeMap.containsKey(reverseKey)) {
+ RouteInfo reverseRoute = routeMap.get(reverseKey);
+
+ if (!processedIds.contains(reverseRoute.getRoute_id())) {
+ // 选择routeId较小的作为主记录,导航模式改为2(双向)
+ RouteInfo bidirectionalRoute = route.getRoute_id() < reverseRoute.getRoute_id() ? route : reverseRoute;
+ bidirectionalRoute.setNavigation_mode("2");
+ mergedData.add(bidirectionalRoute);
+
+ processedIds.add(route.getRoute_id());
+ processedIds.add(reverseRoute.getRoute_id());
+ }
+ } else {
+ // 没有反向路径,直接添加
+ mergedData.add(route);
+ processedIds.add(route.getRoute_id());
+ }
+ }
+
+ return mergedData;
+ }
}
diff --git a/src/main/java/org/nl/apt15e/common/logging/aspect/LogAspect.java b/src/main/java/org/nl/apt15e/common/logging/aspect/LogAspect.java
index 5d38b61..fce0306 100644
--- a/src/main/java/org/nl/apt15e/common/logging/aspect/LogAspect.java
+++ b/src/main/java/org/nl/apt15e/common/logging/aspect/LogAspect.java
@@ -12,20 +12,13 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
+import org.nl.apt15e.common.logging.annotation.Log;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+
/**
* @author dsh
@@ -44,23 +37,63 @@ public class LogAspect {
/**
* 环绕通知
- * @param joinPoint
+ * @param point
* @return
* @throws Throwable
*/
@Around("logPointCut()")
- public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
-// MethodSignature signature = (MethodSignature) joinPoint.getSignature();
-
-// String params = JSONObject.toJSONString(joinPoint.getArgs());
+ public Object logAround(ProceedingJoinPoint point) throws Throwable {
+//// MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//
-//
- Object result;
-// log.info("【日志注解】开始执行 -- {}:{} {}", className, methodName, params);
- result = joinPoint.proceed();
-// log.info("返回参数:{}" ,JSONObject.toJSONString(result));
+//// String params = JSONObject.toJSONString(joinPoint.getArgs());
+////
+////
+// Object result;
+//// log.info("【日志注解】开始执行 -- {}:{} {}", className, methodName, params);
+// result = joinPoint.proceed();
+//// log.info("返回参数:{}" ,JSONObject.toJSONString(result));
+// return result;
+ Object result = null;
+ long beginTime = System.currentTimeMillis();
+ try {
+ // 执行方法
+ result = point.proceed();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ // 执行时长(毫秒)
+ long time = System.currentTimeMillis() - beginTime;
+ // 保存日志
+ saveLog(point, time);
return result;
}
+ private void saveLog(ProceedingJoinPoint joinPoint, long time) {
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+ Log logAnnotation = method.getAnnotation(Log.class);
+ // 注解上的描述
+ String description = "";
+ if (logAnnotation != null) {
+ description = logAnnotation.value();
+ }
+ // 请求的方法名
+ String className = joinPoint.getTarget().getClass().getName();
+ String methodName = signature.getName();
+ // 请求的方法参数值
+ Object[] args = joinPoint.getArgs();
+ // 请求的方法参数名称
+ LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
+ String[] paramNames = u.getParameterNames(method);
+ String params = "";
+ if (args != null && paramNames != null) {
+
+ for (int i = 0; i < args.length; i++) {
+ params += " " + paramNames[i] + ": " + args[i];
+ }
+ }
+ log.info("【日志注解】开始执行 -- 描述:{} -- 类方法:{}.{}() -- 参数:{} -- 执行时长:{}毫秒", description, className, methodName, params, time);
+ }
+
}
diff --git a/src/main/java/org/nl/apt15e/config/satoken/SaTokenConfig.java b/src/main/java/org/nl/apt15e/config/satoken/SaTokenConfig.java
new file mode 100644
index 0000000..75a170a
--- /dev/null
+++ b/src/main/java/org/nl/apt15e/config/satoken/SaTokenConfig.java
@@ -0,0 +1,32 @@
+package org.nl.apt15e.config.satoken;
+
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpUtil;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+/**
+ * @author dsh
+ * 2025/10/22
+ */
+@Configuration
+public class SaTokenConfig implements WebMvcConfigurer {
+
+ @Resource
+ private SecurityProperties securityProperties;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new SaInterceptor(handle -> {
+ SaRouter
+ .match("/**")
+ .check(r -> StpUtil.checkLogin());
+ }))
+ .addPathPatterns("/**")
+ .excludePathPatterns(securityProperties.getExcludes());
+ }
+}
diff --git a/src/main/java/org/nl/apt15e/config/satoken/SecurityProperties.java b/src/main/java/org/nl/apt15e/config/satoken/SecurityProperties.java
new file mode 100644
index 0000000..3f0269b
--- /dev/null
+++ b/src/main/java/org/nl/apt15e/config/satoken/SecurityProperties.java
@@ -0,0 +1,21 @@
+package org.nl.apt15e.config.satoken;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author dsh
+ * 2025/10/22
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "security")
+public class SecurityProperties {
+
+ /**
+ * 排除路径
+ */
+ private String[] excludes;
+
+}
diff --git a/src/main/java/org/nl/apt15e/manage/logging/controller/LogController.java b/src/main/java/org/nl/apt15e/manage/logging/controller/LogController.java
new file mode 100644
index 0000000..d26c919
--- /dev/null
+++ b/src/main/java/org/nl/apt15e/manage/logging/controller/LogController.java
@@ -0,0 +1,74 @@
+package org.nl.apt15e.manage.logging.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import org.nl.apt15e.common.BadRequestException;
+import org.nl.apt15e.common.logging.annotation.Log;
+import org.nl.apt15e.manage.logging.dto.LogFileDTO;
+import org.nl.apt15e.manage.logging.service.LogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+/**
+ * @author dsh
+ * 2025/11/3
+ */
+@RestController
+@RequestMapping("/api/logs")
+public class LogController {
+
+ @Autowired
+ private LogService logService;
+
+ /**
+ * 获取日志文件列表
+ */
+ @Log("获取日志文件列表")
+ @GetMapping("/list")
+ public ResponseEntity