add:添加示教接口
This commit is contained in:
34
src/main/java/org/nl/apt15e/Apt15EApplication.java
Normal file
34
src/main/java/org/nl/apt15e/Apt15EApplication.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package org.nl.apt15e;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@EnableAsync
|
||||||
|
@EnableScheduling
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@RestController
|
||||||
|
@MapperScan("org.nl.apt15e.**.config")
|
||||||
|
public class Apt15EApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Apt15EApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问首页提示
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "Backend service started successfully";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
src/main/java/org/nl/apt15e/apt/dao/VehicleException.java
Normal file
26
src/main/java/org/nl/apt15e/apt/dao/VehicleException.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package org.nl.apt15e.apt.dao;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VehicleException implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误信息
|
||||||
|
*/
|
||||||
|
private List<String> exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private List<Long> exceptionCodes;
|
||||||
|
|
||||||
|
}
|
||||||
65
src/main/java/org/nl/apt15e/apt/dao/VehicleInfo.java
Normal file
65
src/main/java/org/nl/apt15e/apt/dao/VehicleInfo.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package org.nl.apt15e.apt.dao;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VehicleInfo implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆 ID
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆 IP
|
||||||
|
*/
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆所在地图 ID
|
||||||
|
*/
|
||||||
|
private Long mapId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆所在地图 名称
|
||||||
|
*/
|
||||||
|
private String mapName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆状态 ID
|
||||||
|
*/
|
||||||
|
private Long stateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆状态名称
|
||||||
|
*/
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域 ID
|
||||||
|
*/
|
||||||
|
private Long areaId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量
|
||||||
|
*/
|
||||||
|
private Long batteryPower;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常信息
|
||||||
|
*/
|
||||||
|
private VehicleException exceptionInfo;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.nl.apt15e.apt.rest;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleInfo;
|
||||||
|
import org.nl.apt15e.apt.service.VehicleInfoService;
|
||||||
|
import org.nl.apt15e.common.logging.annotation.Log;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/vehicle")
|
||||||
|
public class VehicleInfoController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private VehicleInfoService vehicleInfoService;
|
||||||
|
|
||||||
|
@GetMapping("/getVehicleInfo")
|
||||||
|
// @Log("获取车辆信息")
|
||||||
|
public VehicleInfo getVehicleInfo() {
|
||||||
|
return vehicleInfoService.getVehicleInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.nl.apt15e.apt.service;
|
||||||
|
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/2
|
||||||
|
*/
|
||||||
|
public interface VehicleInfoService {
|
||||||
|
|
||||||
|
VehicleInfo getVehicleInfo();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package org.nl.apt15e.apt.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleException;
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleInfo;
|
||||||
|
import org.nl.apt15e.apt.service.VehicleInfoService;
|
||||||
|
import org.nl.apt15e.apt.websocket.WebSocketVehicleServer;
|
||||||
|
import org.nl.apt15e.util.HTTPUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/2
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class VehicleInfoServiceImpl implements VehicleInfoService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TaskScheduler scheduler;
|
||||||
|
|
||||||
|
public static VehicleInfo vehicleInfo = new VehicleInfo();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VehicleInfo getVehicleInfo() {
|
||||||
|
return vehicleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async("asynchronousTasks")
|
||||||
|
public void queryVehicleInfo() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.get("http://192.168.100.82:8081","/amr/onlineAmr",null);
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response!=null && response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
String body = response.body();
|
||||||
|
JSONArray jsonArray = JSONObject.parseObject(body).getJSONArray("data");
|
||||||
|
if (jsonArray.isEmpty()) {
|
||||||
|
log.info("车辆数据为空");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
JSONObject data = jsonArray.getJSONObject(i);
|
||||||
|
vehicleInfo = JSONObject.toJavaObject(data, VehicleInfo.class);
|
||||||
|
//电量
|
||||||
|
vehicleInfo.setBatteryPower(data.getLong("batteryPercentile"));
|
||||||
|
//上报的异常信息
|
||||||
|
VehicleException vehicleException = JSONObject.toJavaObject(data.getJSONObject("amrException"), VehicleException.class);
|
||||||
|
vehicleInfo.setExceptionInfo(vehicleException);
|
||||||
|
System.out.println("Response Body: " + data);
|
||||||
|
System.out.println("vehicleInfo: " + vehicleInfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("查询调度车辆信息失败:{}",response);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问调度报错{}", e.getMessage());
|
||||||
|
}
|
||||||
|
if (response != null) {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async("asynchronousTasks")
|
||||||
|
public void sendVehicleInfo() {
|
||||||
|
CopyOnWriteArraySet<WebSocketVehicleServer> webSocketSet =
|
||||||
|
WebSocketVehicleServer.getWebSocketSet();
|
||||||
|
if (webSocketSet.size() > 0) {
|
||||||
|
webSocketSet.forEach(c -> {
|
||||||
|
Map<String, Object> vehicleInfoMap = new HashMap<>();
|
||||||
|
vehicleInfoMap.put("data", vehicleInfo);
|
||||||
|
c.sendDataToClient(vehicleInfoMap);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
scheduler.scheduleAtFixedRate(this::queryVehicleInfo,4000);
|
||||||
|
scheduler.scheduleAtFixedRate(this::sendVehicleInfo, 4000);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
src/main/java/org/nl/apt15e/apt/station/dao/Station.java
Normal file
50
src/main/java/org/nl/apt15e/apt/station/dao/Station.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package org.nl.apt15e.apt.station.dao;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/4
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Station implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点标识
|
||||||
|
*/
|
||||||
|
private String station_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点编码 对应地图上站点
|
||||||
|
*/
|
||||||
|
private String station_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点别名
|
||||||
|
*/
|
||||||
|
private String station_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动作类型
|
||||||
|
*/
|
||||||
|
private String action_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* x坐标
|
||||||
|
*/
|
||||||
|
private Double x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* y坐标
|
||||||
|
*/
|
||||||
|
private Double y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角度
|
||||||
|
*/
|
||||||
|
private Double angle;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.nl.apt15e.apt.teaching.rest;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.nl.apt15e.apt.teaching.service.TeachingService;
|
||||||
|
import org.nl.apt15e.common.logging.annotation.Log;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/teaching")
|
||||||
|
public class TeachingController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TeachingService teachingService;
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/startMapping")
|
||||||
|
// @Log("开始建图")
|
||||||
|
private ResponseEntity<Object> startMapping(@RequestParam("mapName") String mapName) {
|
||||||
|
return new ResponseEntity<>(teachingService.startMapping(mapName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/stopMapping")
|
||||||
|
private ResponseEntity<Object> stopMapping() {
|
||||||
|
return new ResponseEntity<>(teachingService.stopMapping(), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/setStation")
|
||||||
|
private ResponseEntity<Object> setStation(@RequestParam("stationName") String stationName) {
|
||||||
|
return new ResponseEntity<>(teachingService.setStation(stationName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/deployRunMap")
|
||||||
|
private ResponseEntity<Object> deployRunMap(@RequestParam("mapName") String mapName) {
|
||||||
|
return new ResponseEntity<>(teachingService.deployRunMap(mapName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/changeCurrentRunMap")
|
||||||
|
private ResponseEntity<Object> changeCurrentRunMap(@RequestParam("mapName") String mapName) {
|
||||||
|
return new ResponseEntity<>(teachingService.changeCurrentRunMap(mapName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getLocalMaps")
|
||||||
|
private ResponseEntity<Object> getLocalMaps() {
|
||||||
|
return new ResponseEntity<>(teachingService.getLocalMaps(), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getRunMapZip")
|
||||||
|
private ResponseEntity<Object> getRunMapZip(@RequestParam("mapName") String mapName) {
|
||||||
|
return new ResponseEntity<>(teachingService.getRunMapZip(mapName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/synchronizeMap")
|
||||||
|
private ResponseEntity<Object> synchronizeMap(@RequestParam("mapName") String mapName) {
|
||||||
|
return new ResponseEntity<>(teachingService.synchronizeMap(mapName), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/restart")
|
||||||
|
private ResponseEntity<Object> restart() {
|
||||||
|
return new ResponseEntity<>(teachingService.restart(), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/relocate")
|
||||||
|
private ResponseEntity<Object> relocate(@RequestParam("x") Double x, @RequestParam("y") Double y, @RequestParam("angle") Double angle) {
|
||||||
|
return new ResponseEntity<>(teachingService.relocate(x, y, angle), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package org.nl.apt15e.apt.teaching.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
public interface TeachingService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始建图
|
||||||
|
*/
|
||||||
|
Map<String, Object> startMapping(String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切手动
|
||||||
|
*/
|
||||||
|
Map<String, Object> startManual();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切自动
|
||||||
|
*/
|
||||||
|
Map<String, Object> stopManual();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束建图
|
||||||
|
*/
|
||||||
|
Map<String, Object> stopMapping();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 建图过程中设置站点
|
||||||
|
*/
|
||||||
|
Map<String, Object> setStation(String stationName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取后台地图列表
|
||||||
|
*/
|
||||||
|
Map<String, Object> getLocalMaps();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部署地图
|
||||||
|
* @param mapName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> deployRunMap(String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用地图
|
||||||
|
* @param mapName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> changeCurrentRunMap(String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取主机地图包
|
||||||
|
* @param mapName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
File getRunMapZip(String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步地图到调度
|
||||||
|
*/
|
||||||
|
Map<String, Object> synchronizeMap(String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定位
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param angle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> relocate(Double x,Double y,Double angle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启车辆后台程序
|
||||||
|
*/
|
||||||
|
Map<String, Object> restart();
|
||||||
|
}
|
||||||
@@ -0,0 +1,350 @@
|
|||||||
|
package org.nl.apt15e.apt.teaching.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleException;
|
||||||
|
import org.nl.apt15e.apt.dao.VehicleInfo;
|
||||||
|
import org.nl.apt15e.apt.teaching.service.TeachingService;
|
||||||
|
import org.nl.apt15e.common.BadRequestException;
|
||||||
|
import org.nl.apt15e.util.HTTPUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class TeachingServiceImpl implements TeachingService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> startMapping(String mapName) {
|
||||||
|
if ("".equals(mapName)){
|
||||||
|
throw new BadRequestException("mapName is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("name", mapName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/startMapping", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体开始建图接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("开始建图失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("开始建图:{}",body);
|
||||||
|
if ("200".equals(body.getString("code"))){
|
||||||
|
body =(JSONObject) this.startManual();
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("开始建图失败");
|
||||||
|
throw new BadRequestException("开始建图失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> startManual() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/startManual", new JSONObject());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体切手动接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("切手动失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("切手动:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("切手动失败");
|
||||||
|
throw new BadRequestException("切手动失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> stopManual() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/stopManual", new JSONObject());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体切自动接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("切自动失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("切自动:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("切自动失败");
|
||||||
|
throw new BadRequestException("切自动失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> stopMapping() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/stopMapping", new JSONObject());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体结束建图接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("结束建图失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("结束建图:{}",body);
|
||||||
|
if ("200".equals(body.getString("code"))){
|
||||||
|
body =(JSONObject) this.stopManual();
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("结束建图失败");
|
||||||
|
throw new BadRequestException("结束建图失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> setStation(String stationName) {
|
||||||
|
if ("".equals(stationName)){
|
||||||
|
throw new BadRequestException("spotCode is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("spotCode", stationName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/setStates", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体设置站点接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("设置站点失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("设置站点:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("设置站点失败");
|
||||||
|
throw new BadRequestException("设置站点失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getLocalMaps() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.get("http://192.168.100.82:9998","/tool/editor/getLocalMaps", new JSONObject());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体地图列表接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("获取地图列表失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("获取地图列表:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("获取地图列表失败");
|
||||||
|
throw new BadRequestException("获取地图列表失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> deployRunMap(String mapName) {
|
||||||
|
if ("".equals(mapName)){
|
||||||
|
throw new BadRequestException("mapName is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("id", mapName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/deployRunMap", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体部署地图接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("部署地图失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("部署地图:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("部署地图失败");
|
||||||
|
throw new BadRequestException("部署地图失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> changeCurrentRunMap(String mapName) {
|
||||||
|
if ("".equals(mapName)){
|
||||||
|
throw new BadRequestException("mapName is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("name", mapName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/changeCurrentRunMap", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体应用地图接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("应用地图失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("应用地图:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("应用地图失败");
|
||||||
|
throw new BadRequestException("应用地图失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getRunMapZip(String mapName) {
|
||||||
|
if ("".equals(mapName)){
|
||||||
|
throw new BadRequestException("mapName is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("name", mapName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/getRunMapZip", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体地图包接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("获取地图包失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
// JSONObject body = JSON.parseObject(response.body());
|
||||||
|
// 3. 将响应体写入临时ZIP文件
|
||||||
|
byte[] zipBytes = response.bodyBytes();
|
||||||
|
File fileName = new File(mapName);
|
||||||
|
File tempZipFile = FileUtil.writeBytes(zipBytes, FileUtil.createTempFile(fileName));
|
||||||
|
|
||||||
|
// 4. 解压ZIP文件
|
||||||
|
// File unzipDir = ZipUtil.unzip(tempZipFile, Charset.defaultCharset());
|
||||||
|
|
||||||
|
// 5. 处理解压后的文件
|
||||||
|
// File[] files = unzipDir.listFiles();
|
||||||
|
// if (files != null) {
|
||||||
|
// for (File file : files) {
|
||||||
|
// System.out.println("文件名: " + file.getName());
|
||||||
|
// System.out.println("文件内容: ");
|
||||||
|
// System.out.println(FileUtil.readUtf8String(file)); // 读取文本内容
|
||||||
|
// // 如果是二进制文件,使用:FileUtil.readBytes(file)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 6. 清理临时文件(可选)
|
||||||
|
// FileUtil.del(tempZipFile);
|
||||||
|
// FileUtil.del(unzipDir);
|
||||||
|
log.info("获取地图包");
|
||||||
|
return tempZipFile;
|
||||||
|
}
|
||||||
|
log.info("获取地图包失败");
|
||||||
|
throw new BadRequestException("获取地图包失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> synchronizeMap(String mapName) {
|
||||||
|
File zipFile = this.getRunMapZip(mapName);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HttpRequest.post("http://192.168.100.82:8081/map/uploadFile")
|
||||||
|
.setConnectionTimeout(3000)
|
||||||
|
.setReadTimeout(3000)
|
||||||
|
.header("token", "admin123")
|
||||||
|
.header("name", "lx-script")
|
||||||
|
.header("Content-Type", "multipart/form-data;charset=UTF-8")
|
||||||
|
.form("areaId",1)
|
||||||
|
.form("areaName","")
|
||||||
|
.form("data",zipFile)
|
||||||
|
.execute();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("同步地图到调度接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("同步地图失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("同步地图:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("同步地图失败");
|
||||||
|
throw new BadRequestException("同步地图失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> relocate(Double x, Double y, Double angle) {
|
||||||
|
if (ObjectUtil.isEmpty(x) || ObjectUtil.isEmpty(y) || ObjectUtil.isEmpty(angle)){
|
||||||
|
throw new BadRequestException("params is empty");
|
||||||
|
}
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("x", x);
|
||||||
|
params.put("y", y);
|
||||||
|
params.put("angle", angle / 180.0 * Math.PI);
|
||||||
|
params.put("noisyX", 0.5);
|
||||||
|
params.put("noisyY", 0.5);
|
||||||
|
params.put("noisyAngle", Math.PI);
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/relocate", params);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体重定位接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("重定位失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("重定位:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("重定位失败");
|
||||||
|
throw new BadRequestException("重定位失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> restart() {
|
||||||
|
HttpResponse response = null;
|
||||||
|
try {
|
||||||
|
response = HTTPUtil.post("http://192.168.100.82:9998","/tool/rob/restart", new JSONObject());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("访问车体程序重启接口报错:{}",e.getMessage());
|
||||||
|
throw new BadRequestException("车体程序重启失败");
|
||||||
|
}
|
||||||
|
// 检查响应状态码
|
||||||
|
if (response.isOk()) {
|
||||||
|
// 获取响应体内容
|
||||||
|
JSONObject body = JSON.parseObject(response.body());
|
||||||
|
log.info("车体程序重启:{}",body);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("车体程序重启失败");
|
||||||
|
throw new BadRequestException("车体程序重启失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package org.nl.apt15e.apt.websocket;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.websocket.*;
|
||||||
|
import javax.websocket.server.PathParam;
|
||||||
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@ServerEndpoint("/webSocket/VehicleInfo/{sid}")
|
||||||
|
@Component
|
||||||
|
public class WebSocketVehicleServer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
|
||||||
|
*/
|
||||||
|
private static CopyOnWriteArraySet<WebSocketVehicleServer> webSocketSet = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
||||||
|
*/
|
||||||
|
private static int onlineCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
|
||||||
|
*/
|
||||||
|
private Session session;
|
||||||
|
/**
|
||||||
|
* 接收userId
|
||||||
|
*/
|
||||||
|
private String sid = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接建立成功调用的方法
|
||||||
|
*/
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session, @PathParam("sid") String sid) {
|
||||||
|
this.session = session;
|
||||||
|
//如果存在就先删除一个,防止重复推送消息
|
||||||
|
webSocketSet.removeIf(webSocket -> webSocket.sid.equals(sid));
|
||||||
|
webSocketSet.add(this);
|
||||||
|
//在线数加1
|
||||||
|
addOnlineCount();
|
||||||
|
log.info("VehicleWS:sid{}连接成功,当前在线人数为{}", sid, getOnlineCount());
|
||||||
|
this.sid = sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接关闭调用的方法
|
||||||
|
*/
|
||||||
|
@OnClose
|
||||||
|
public void onClose() {
|
||||||
|
webSocketSet.remove(this);
|
||||||
|
//在线数减1
|
||||||
|
subOnlineCount();
|
||||||
|
log.info("VehicleWS:sid{}关闭连接!当前在线人数为{}", sid, getOnlineCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到客户端消息后调用的方法
|
||||||
|
*
|
||||||
|
* @param message 客户端发送过来的消息
|
||||||
|
*/
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(String message, Session session) {
|
||||||
|
//System.out.println(webSocketSet.size() + "_接收到消息_" + session.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnError
|
||||||
|
public void onError(Session session, Throwable error) {
|
||||||
|
//log.error("发生错误");
|
||||||
|
webSocketSet.remove(session);
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session getSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息,在定时任务中会调用此方法
|
||||||
|
public void sendMessage(String message) throws IOException {
|
||||||
|
this.session.getBasicRemote().sendText(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void sendDataToClient(Map<String, Object> data) {
|
||||||
|
try {
|
||||||
|
if (this.session != null&& MapUtil.isNotEmpty(data)) {
|
||||||
|
this.session.getBasicRemote().sendText(JSON.toJSONString(data));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("发送消息给客户端失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static synchronized int getOnlineCount() {
|
||||||
|
return onlineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CopyOnWriteArraySet<WebSocketVehicleServer> getWebSocketSet() {
|
||||||
|
return webSocketSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSession(Session session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void addOnlineCount() {
|
||||||
|
WebSocketVehicleServer.onlineCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void subOnlineCount() {
|
||||||
|
WebSocketVehicleServer.onlineCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/main/java/org/nl/apt15e/common/BadRequestException.java
Normal file
25
src/main/java/org/nl/apt15e/common/BadRequestException.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package org.nl.apt15e.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class BadRequestException extends RuntimeException{
|
||||||
|
|
||||||
|
private Integer status = BAD_REQUEST.value();
|
||||||
|
|
||||||
|
public BadRequestException(String msg){
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadRequestException(HttpStatus status, String msg){
|
||||||
|
super(msg);
|
||||||
|
this.status = status.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/main/java/org/nl/apt15e/common/exception/ApiError.java
Normal file
49
src/main/java/org/nl/apt15e/common/exception/ApiError.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.nl.apt15e.common.exception;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
class ApiError {
|
||||||
|
|
||||||
|
private Integer code = 400;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime Date;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private ApiError() {
|
||||||
|
Date = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiError error(String message){
|
||||||
|
ApiError apiError = new ApiError();
|
||||||
|
apiError.setMessage(message);
|
||||||
|
return apiError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiError error(Integer status, String message){
|
||||||
|
ApiError apiError = new ApiError();
|
||||||
|
apiError.setCode(status);
|
||||||
|
apiError.setMessage(message);
|
||||||
|
return apiError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package org.nl.apt15e.common.exception;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nl.apt15e.common.BadRequestException;
|
||||||
|
import org.nl.apt15e.util.ThrowableUtil;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有不可知的异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Throwable.class)
|
||||||
|
public ResponseEntity<ApiError> handleException(Throwable e){
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return buildResponseEntity(ApiError.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token 无效的异常拦截
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// @ExceptionHandler(value = NotLoginException.class)
|
||||||
|
// public ResponseEntity<ApiError> notLoginException(Exception e) {
|
||||||
|
//// log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
// return buildResponseEntity(ApiError.error(401,"token 失效"));
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理自定义异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = BadRequestException.class)
|
||||||
|
public ResponseEntity<ApiError> badRequestException(BadRequestException e) {
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
log.info(e.getMessage());
|
||||||
|
return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有接口数据验证异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public ResponseEntity<ApiError> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
|
||||||
|
// 打印堆栈信息
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
|
||||||
|
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
|
||||||
|
String msg = "不能为空";
|
||||||
|
if(msg.equals(message)){
|
||||||
|
message = str[1] + ":" + message;
|
||||||
|
}
|
||||||
|
return buildResponseEntity(ApiError.error(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一返回
|
||||||
|
*/
|
||||||
|
private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) {
|
||||||
|
return new ResponseEntity<>(apiError, HttpStatus.valueOf(apiError.getCode()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.nl.apt15e.common.logging.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Log {
|
||||||
|
String value() default "";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package org.nl.apt15e.common.logging.aspect;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.Signature;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
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
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class LogAspect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置切入点
|
||||||
|
*/
|
||||||
|
@Pointcut("@annotation(org.nl.apt15e.common.logging.annotation.Log)")
|
||||||
|
public void logPointCut(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 环绕通知
|
||||||
|
* @param joinPoint
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
@Around("logPointCut()")
|
||||||
|
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
// MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
// Method method = signature.getMethod();
|
||||||
|
// String className = joinPoint.getTarget().getClass().getName();
|
||||||
|
// 方法路径
|
||||||
|
// String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
|
||||||
|
// String params = JSONObject.toJSONString(joinPoint.getArgs());
|
||||||
|
|
||||||
|
|
||||||
|
Object result;
|
||||||
|
// log.info("【日志注解】开始执行 -- {}:{} {}", className, "111", params);
|
||||||
|
result = joinPoint.proceed();
|
||||||
|
// log.info("返回参数:{}" ,JSONObject.toJSONString(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.nl.apt15e.config.thread;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步任务线程池装配类
|
||||||
|
*
|
||||||
|
* @author https://juejin.im/entry/5abb8f6951882555677e9da2
|
||||||
|
* @date 2019年10月31日15:06:18
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
@EnableAsync
|
||||||
|
public class AsyncTaskExecutePool implements AsyncConfigurer{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Executor getAsyncExecutor() {
|
||||||
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
|
//核心线程池大小
|
||||||
|
executor.setCorePoolSize(20);
|
||||||
|
//最大线程数
|
||||||
|
executor.setMaxPoolSize(50);
|
||||||
|
//队列容量
|
||||||
|
executor.setQueueCapacity(50);
|
||||||
|
//活跃时间
|
||||||
|
executor.setKeepAliveSeconds(60);
|
||||||
|
//线程名字前缀
|
||||||
|
executor.setThreadNamePrefix("Async-");
|
||||||
|
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
|
||||||
|
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
|
||||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
executor.initialize();
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池配置
|
||||||
|
*/
|
||||||
|
@Bean(name = "asynchronousTasks")
|
||||||
|
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
|
||||||
|
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
|
||||||
|
// 核心线程池大小
|
||||||
|
threadPoolTaskExecutor.setCorePoolSize(20);
|
||||||
|
// 最大线程数
|
||||||
|
threadPoolTaskExecutor.setMaxPoolSize(50);
|
||||||
|
// 队列容量
|
||||||
|
threadPoolTaskExecutor.setQueueCapacity(50);
|
||||||
|
// 活跃时间
|
||||||
|
threadPoolTaskExecutor.setKeepAliveSeconds(60);
|
||||||
|
// 主线程等待子线程执行时间
|
||||||
|
threadPoolTaskExecutor.setAwaitTerminationSeconds(50);
|
||||||
|
// threadPoolTaskExecutor.setAwaitTerminationSeconds(30);
|
||||||
|
// 线程名字前缀
|
||||||
|
threadPoolTaskExecutor.setThreadNamePrefix("apt-thread-");
|
||||||
|
// RejectedExecutionHandler:当pool已经达到max-size的时候,如何处理新任务
|
||||||
|
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
|
||||||
|
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
// 初始化
|
||||||
|
threadPoolTaskExecutor.initialize();
|
||||||
|
return threadPoolTaskExecutor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.nl.apt15e.config.thread;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/3
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WebSocketConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServerEndpointExporter serverEndpointExporter() {
|
||||||
|
return new ServerEndpointExporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
40
src/main/java/org/nl/apt15e/util/HTTPUtil.java
Normal file
40
src/main/java/org/nl/apt15e/util/HTTPUtil.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package org.nl.apt15e.util;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsh
|
||||||
|
* 2025/7/2
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class HTTPUtil {
|
||||||
|
|
||||||
|
public static HttpResponse post(String url, String method, JSONObject params)throws Exception{
|
||||||
|
String sendUrl = url + method;
|
||||||
|
return HttpRequest.post(sendUrl)
|
||||||
|
.setConnectionTimeout(3000)
|
||||||
|
.setReadTimeout(3000)
|
||||||
|
.header("token", "admin123")
|
||||||
|
.header("name", "lx-script")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(String.valueOf(params))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpResponse get(String url, String method, JSONObject params)throws Exception{
|
||||||
|
String sendUrl = url + method;
|
||||||
|
return HttpRequest.get(sendUrl)
|
||||||
|
.setConnectionTimeout(3000)
|
||||||
|
.setReadTimeout(3000)
|
||||||
|
.header("token", "admin123")
|
||||||
|
.header("name", "lx-script")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.form(params)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/java/org/nl/apt15e/util/ThrowableUtil.java
Normal file
22
src/main/java/org/nl/apt15e/util/ThrowableUtil.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package org.nl.apt15e.util;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liejiu
|
||||||
|
*/
|
||||||
|
public class ThrowableUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取堆栈信息
|
||||||
|
*/
|
||||||
|
public static String getStackTrace(Throwable throwable){
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
try (PrintWriter pw = new PrintWriter(sw)) {
|
||||||
|
throwable.printStackTrace(pw);
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/main/resources/banner.txt
Normal file
8
src/main/resources/banner.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
_ _ ___________ _ _____ _ ___________ _____
|
||||||
|
| \ | | _ | ___ \ | | ___| | | ___| ___|_ _|
|
||||||
|
| \| | | | | |_/ / | | |__ | | | |__ | |_ | |
|
||||||
|
| . ` | | | | ___ \ | | __|| | | __|| _| | |
|
||||||
|
| |\ \ \_/ / |_/ / |____| |___| |____| |___| | | |
|
||||||
|
\_| \_/\___/\____/\_____/\____/\_____/\____/\_| \_/
|
||||||
|
|
||||||
|
:: Spring Boot :: (v2.6.13.RELEASE)
|
||||||
52
src/main/resources/config/application-dev.yml
Normal file
52
src/main/resources/config/application-dev.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
server:
|
||||||
|
# 端口
|
||||||
|
port: 8081
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/apt_data?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
# 初始连接数
|
||||||
|
initial-size: 5
|
||||||
|
# 最小连接数
|
||||||
|
min-idle: 15
|
||||||
|
# 最大连接数
|
||||||
|
max-active: 30
|
||||||
|
# 超时时间(以秒数为单位)
|
||||||
|
remove-abandoned-timeout: 180
|
||||||
|
# 获取连接超时时间
|
||||||
|
max-wait: 3000
|
||||||
|
# 连接有效性检测时间
|
||||||
|
time-between-eviction-runs-millis: 60000
|
||||||
|
# 连接在池中最小生存的时间
|
||||||
|
min-evictable-idle-time-millis: 300000
|
||||||
|
# 连接在池中最大生存的时间
|
||||||
|
max-evictable-idle-time-millis: 900000
|
||||||
|
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
|
||||||
|
test-while-idle: true
|
||||||
|
# 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
|
||||||
|
test-on-borrow: true
|
||||||
|
# 是否在归还到池中前进行检验
|
||||||
|
test-on-return: false
|
||||||
|
# 检测连接是否有效
|
||||||
|
validation-query: select 1
|
||||||
|
# 配置监控统计
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
stat-view-servlet:
|
||||||
|
enabled: true
|
||||||
|
url-pattern: /druid/*
|
||||||
|
reset-enable: false
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
# 记录慢SQL
|
||||||
|
log-slow-sql: true
|
||||||
|
slow-sql-millis: 1000
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
52
src/main/resources/config/application-pro.yml
Normal file
52
src/main/resources/config/application-pro.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
server:
|
||||||
|
# 端口
|
||||||
|
port: 8081
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/apt_data?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
# 初始连接数
|
||||||
|
initial-size: 5
|
||||||
|
# 最小连接数
|
||||||
|
min-idle: 15
|
||||||
|
# 最大连接数
|
||||||
|
max-active: 30
|
||||||
|
# 超时时间(以秒数为单位)
|
||||||
|
remove-abandoned-timeout: 180
|
||||||
|
# 获取连接超时时间
|
||||||
|
max-wait: 3000
|
||||||
|
# 连接有效性检测时间
|
||||||
|
time-between-eviction-runs-millis: 60000
|
||||||
|
# 连接在池中最小生存的时间
|
||||||
|
min-evictable-idle-time-millis: 300000
|
||||||
|
# 连接在池中最大生存的时间
|
||||||
|
max-evictable-idle-time-millis: 900000
|
||||||
|
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
|
||||||
|
test-while-idle: true
|
||||||
|
# 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
|
||||||
|
test-on-borrow: true
|
||||||
|
# 是否在归还到池中前进行检验
|
||||||
|
test-on-return: false
|
||||||
|
# 检测连接是否有效
|
||||||
|
validation-query: select 1
|
||||||
|
# 配置监控统计
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
stat-view-servlet:
|
||||||
|
enabled: true
|
||||||
|
url-pattern: /druid/*
|
||||||
|
reset-enable: false
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
# 记录慢SQL
|
||||||
|
log-slow-sql: true
|
||||||
|
slow-sql-millis: 1000
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
18
src/main/resources/config/application.yml
Normal file
18
src/main/resources/config/application.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
jackson:
|
||||||
|
time-zone: GMT+8
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: false
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
global-config:
|
||||||
|
banner: false
|
||||||
|
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
path: logs
|
||||||
|
config: classpath:logback-spring.xml
|
||||||
69
src/main/resources/logback-spring.xml
Normal file
69
src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- 级别[ALL< Trace < DEBUG < INFO < WARN < ERROR < FATAL < OFF] -->
|
||||||
|
<!-- monitorInterval(单位s)指定log4j自动重新配置的监测间隔时间-->
|
||||||
|
<configuration scan="true" scanPeriod="30 seconds" debug="false">
|
||||||
|
<property name="log.charset" value="utf-8"/>
|
||||||
|
<property name="log.pattern" value="%black(nlAdmin-) %red(%d{yyyy-MM-dd HH:mm:ss.SSS}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36} - %method) - %white(%msg%n)"/>
|
||||||
|
<SpringProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
|
||||||
|
<property name="LOG_HOME" value="${logPath}"/>
|
||||||
|
|
||||||
|
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
<charset>${log.charset}</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 appender class 中的log.pattern 表示日志滚动输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<!-- 日志首次输出的文件地址 -->
|
||||||
|
<!-- <file>${LOG_HOME}/info.log</file>-->
|
||||||
|
<!-- 滚动输出策略:基于时间创建日志文件 ,这样第二天输出的日志,就会按照 fileNamePattern 新建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${LOG_HOME}/root/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>30</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<!-- 日志内容输出格式设置为定义好的 log.pattern-->
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||||
|
<charset>${log.charset}</charset>
|
||||||
|
</encoder>
|
||||||
|
<!-- 日志内容输出过滤器 -->
|
||||||
|
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
|
||||||
|
<!-- <!– 过滤的级别 –>-->
|
||||||
|
<!-- <level>INFO</level>-->
|
||||||
|
<!-- <!– 匹配时的操作:接收(记录) –>-->
|
||||||
|
<!-- <onMatch>ACCEPT</onMatch>-->
|
||||||
|
<!-- <!– 不匹配时的操作:拒绝(不记录) –>-->
|
||||||
|
<!-- <onMismatch>DENY</onMismatch>-->
|
||||||
|
<!-- </filter>-->
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- <appender name="async" class="ch.qos.logback.classic.AsyncAppender">-->
|
||||||
|
<!-- <!– 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 –>-->
|
||||||
|
<!-- <discardingThreshold>0</discardingThreshold>-->
|
||||||
|
<!-- <queueSize>256</queueSize>-->
|
||||||
|
<!-- <appender-ref ref="console"/>-->
|
||||||
|
<!-- </appender>-->
|
||||||
|
|
||||||
|
<!-- <appender name="async_file_info" class="ch.qos.logback.classic.AsyncAppender">-->
|
||||||
|
<!-- <discardingThreshold>0</discardingThreshold>-->
|
||||||
|
<!-- <queueSize>256</queueSize>-->
|
||||||
|
<!-- <appender-ref ref="file_info"/>-->
|
||||||
|
<!-- </appender>-->
|
||||||
|
|
||||||
|
<!--系统操作日志 root 根路径的日志级别 info -->
|
||||||
|
<root level="info">
|
||||||
|
<!-- 将定义好的几个日志输出 追加到 root 上 -->
|
||||||
|
<!-- <appender-ref ref="console"/>-->
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
<!-- <appender-ref ref="async_file_info" />-->
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
13
src/test/java/org/nl/apt15e/Apt15EApplicationTests.java
Normal file
13
src/test/java/org/nl/apt15e/Apt15EApplicationTests.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package org.nl.apt15e;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class Apt15EApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user