update:功能

This commit is contained in:
2025-12-01 08:12:11 +08:00
parent d20f559563
commit a9399f5497
51 changed files with 2319 additions and 58 deletions

View File

@@ -24,13 +24,13 @@
<version>2.8.14</version>
</dependency>
<dependency>
<groupId>com.ski.lichuan</groupId>
<groupId>com.ski</groupId>
<artifactId>ski-dashboard-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.ski.lichuan</groupId>
<groupId>com.ski</groupId>
<artifactId>ski-dashboard-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>

View File

@@ -3,9 +3,11 @@ package com.ski.lichuan.admin;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication(scanBasePackages = {"com.ski.lichuan"})
@MapperScan("com.ski.lichuan.mapper")
@EnableScheduling
public class SkiDashboardAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SkiDashboardAdminApplication.class, args);

View File

@@ -53,6 +53,7 @@ public class SecurityConfig {
.authorizeHttpRequests(auth -> auth
// 放行 Swagger UI 相关路径
.requestMatchers(
"/**",
"/api/auth/login",
"/swagger-ui.html",
"/swagger-ui/**",

View File

@@ -0,0 +1,97 @@
package com.ski.lichuan.admin.controller;
import com.ski.lichuan.model.common.HttpResponseData;
import com.ski.lichuan.model.dashboard.TrailPosition;
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
import com.ski.lichuan.services.SnowMachineDeviceService;
import com.ski.lichuan.services.TrailPositionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/options")
@CrossOrigin(origins = "*")
@Tag(name = "公共选项", description = "提供公共的选项数据")
public class OptionsController {
@Autowired
private TrailPositionService trailPositionService;
@Autowired
private SnowMachineDeviceService snowMachineDeviceService;
/**
* 获取所有已绑定雪机的雪道位置信息
*
* @return 已绑定雪机的雪道位置列表
*/
@GetMapping("/boundTrailPositions")
@Operation(summary = "获取已绑定雪机的雪道位置信息", description = "获取所有已绑定雪机的雪道位置信息,用于下拉框选项")
public HttpResponseData<List<TrailPosition>> getBoundTrailPositions() {
HttpResponseData<List<TrailPosition>> responseData = new HttpResponseData<>();
try {
List<TrailPosition> boundPositions = trailPositionService.getBoundTrailPositions();
return responseData.success(boundPositions);
} catch (Exception e) {
return responseData.error("获取已绑定雪机的雪道位置信息失败: " + e.getMessage());
}
}
/**
* 获取所有未绑定位置的雪机设备信息
*
* @return 未绑定位置的雪机设备列表
*/
@GetMapping("/unboundSnowMachines")
@Operation(summary = "获取未绑定位置的雪机设备信息", description = "获取所有未绑定位置的雪机设备信息,用于下拉框选项")
public HttpResponseData<List<SnowMachineDevice>> getUnboundSnowMachines() {
HttpResponseData<List<SnowMachineDevice>> responseData = new HttpResponseData<>();
try {
List<SnowMachineDevice> unboundMachines = snowMachineDeviceService.selectUnboundMachines();
return responseData.success(unboundMachines);
} catch (Exception e) {
return responseData.error("获取未绑定位置的雪机设备信息失败: " + e.getMessage());
}
}
/**
* 获取所有未绑定雪机的雪道位置信息
*
* @return 未绑定雪机的雪道位置列表
*/
@GetMapping("/unboundTrailPositions")
@Operation(summary = "获取未绑定雪机的雪道位置信息", description = "获取所有未绑定雪机的雪道位置信息,用于下拉框选项")
public HttpResponseData<List<TrailPosition>> getUnboundTrailPositions() {
HttpResponseData<List<TrailPosition>> responseData = new HttpResponseData<>();
try {
List<TrailPosition> unboundPositions = trailPositionService.getUnboundTrailPositions();
return responseData.success(unboundPositions);
} catch (Exception e) {
return responseData.error("获取未绑定雪机的雪道位置信息失败: " + e.getMessage());
}
}
/**
* 获取所有雪机设备信息
*
* @return 所有雪机设备列表
*/
@GetMapping("/snowMachineDevices")
@Operation(summary = "获取所有雪机设备信息", description = "获取所有雪机设备信息,用于下拉框选项")
public HttpResponseData<List<SnowMachineDevice>> getAllSnowMachineDevices() {
HttpResponseData<List<SnowMachineDevice>> responseData = new HttpResponseData<>();
try {
List<SnowMachineDevice> allDevices = snowMachineDeviceService.selectAllDevices();
return responseData.success(allDevices);
} catch (Exception e) {
return responseData.error("获取所有雪机设备信息失败: " + e.getMessage());
}
}
}

View File

@@ -77,7 +77,7 @@ public class AuthController {
* @return 用户信息
*/
@GetMapping("/userinfo")
@Operation(summary = "获取当前用户信息", description = "根据JWT Token获取当前登录用户的基本信息",)
@Operation(summary = "获取当前用户信息", description = "根据JWT Token获取当前登录用户的基本信息")
public ResponseEntity<Map<String, Object>> getUserInfo() {
log.info("获取用户信息请求");

View File

@@ -1,7 +1,96 @@
package com.ski.lichuan.admin.controller.device;
import com.ski.lichuan.model.common.HttpResponseData;
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
import com.ski.lichuan.services.SnowMachineDeviceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/device/snowmachine")
@CrossOrigin(origins = "*") // 根据实际需要调整CORS策略
@Tag(name = "造雪机设备", description = "造雪机设备的基本信息管理")
public class SnowMachineController {
@Autowired
private SnowMachineDeviceService snowMachineDeviceService;
/**
* 1.造雪机设备的基本信息管理,增删查改
* 添加造雪机设备
*
* @param snowMachineDevice 造雪机设备信息
* @return 添加结果
*/
}
@PostMapping("/")
@Operation(summary = "添加造雪机设备")
public HttpResponseData<Boolean> addSnowMachine(@RequestBody SnowMachineDevice snowMachineDevice) {
// 调用服务层添加设备
int result = snowMachineDeviceService.addSnowMachineDevice(snowMachineDevice);
return HttpResponseData.ok(result > 0);
}
/**
* 更新造雪机设备信息
*
* @param id 设备ID
* @param snowMachineDevice 更新的设备信息
* @return 更新结果
*/
@PutMapping("/{id}")
@Operation(summary = "更新造雪机设备信息")
public HttpResponseData<Boolean> updateSnowMachine(@PathVariable Integer id, @RequestBody SnowMachineDevice snowMachineDevice) {
snowMachineDevice.setId(id);
int result = snowMachineDeviceService.updateSnowMachineDevice(snowMachineDevice);
return HttpResponseData.ok(result > 0);
}
/**
* 删除造雪机设备
*
* @param id 设备ID
* @return 删除结果
*/
@DeleteMapping("/{id}")
@Operation(summary = "删除造雪机设备")
public HttpResponseData<Boolean> deleteSnowMachine(@PathVariable Integer id) {
// 调用服务层删除设备
int result = snowMachineDeviceService.deleteSnowMachineDevice(id);
return HttpResponseData.ok(result > 0);
}
/**
* 根据ID获取造雪机设备信息
*
* @param id 设备ID
* @return 设备信息
*/
@GetMapping("/{id}")
@Operation(summary = "根据ID获取造雪机设备信息")
public HttpResponseData<SnowMachineDevice> getSnowMachineById(@PathVariable Integer id) {
// 调用服务层获取设备信息
SnowMachineDevice result = snowMachineDeviceService.getSnowMachineDeviceById(id);
log.info("根据ID获取造雪机设备信息ID{}", id);
return HttpResponseData.ok(result);
}
/**
* 获取所有造雪机设备列表
*
* @return 设备列表
*/
@GetMapping("/")
@Operation(summary = "获取所有造雪机设备列表")
public HttpResponseData<List<SnowMachineDevice>> getAllSnowMachines() {
// 调用服务层获取所有设备
List<SnowMachineDevice> result = snowMachineDeviceService.getAllSnowMachineDevices();
return HttpResponseData.ok(result);
}
}

View File

@@ -1,10 +1,177 @@
package com.ski.lichuan.admin.controller.monitor;
public class SkiResortController {
/**
* 1.获取滑雪场雪道和造雪机关联信息
* 2.提供滑雪场雪道和造雪机的关联移除(上下机)接口
* 3.提供滑雪场造雪机的群控功能(只对滑雪场内的造雪机生效)
*/
import com.ski.lichuan.model.common.DeviceEnum;
import com.ski.lichuan.model.common.HttpResponseData;
import com.ski.lichuan.model.dashboard.*;
import com.ski.lichuan.model.device.Impl.SnowMachineDevice;
import com.ski.lichuan.model.device.config.SnowMachineDeviceParams;
import com.ski.lichuan.model.device.config.SnowMachineDevicePitchHorizontalParams;
import com.ski.lichuan.services.TrailPositionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/dashboard")
@CrossOrigin(origins = "*") // 根据实际需要调整CORS策略
@Tag(name = "首页", description = "首页信息展示")
public class SkiResortController {
@Autowired
private TrailPositionService trailPositionService;
@GetMapping("/")
@Operation(summary = "首页-获取滑雪场雪道和造雪机关联信息")
public HttpResponseData<List<List<TrailPosition>>> getDashboardInfo() {
HttpResponseData<List<List<TrailPosition>>> responseData = new HttpResponseData<>();
List<List<TrailPosition>> result = trailPositionService.getAllTrailPositions();
return responseData.success(result);
}
@GetMapping("/positionInfo")
@Operation(summary = "获取雪道坑位的详细信息(造雪机)")
public HttpResponseData<TrailPositionInfo> getPositionInfo(Integer trailPositionId) {
HttpResponseData<TrailPositionInfo> responseData = new HttpResponseData<>();
TrailPositionInfo result = new TrailPositionInfo();
Integer trailId = trailPositionId / 10;
Integer position = trailPositionId % 10;
// 雪机设备
SnowMachineDevice snowMachineDevice = new SnowMachineDevice();
snowMachineDevice.setLora("1234567890123456");
snowMachineDevice.setId(1000000000 + trailPositionId);
snowMachineDevice.setName("造雪机-" + trailPositionId);
snowMachineDevice.setType(DeviceEnum.SNOW_MAKER.getValue());
// 雪道位置信息
TrailPosition trailPosition = new TrailPosition();
trailPosition.setId(trailPositionId);
trailPosition.setTrailId(trailId);
trailPosition.setPosition(position);
trailPosition.setName(trailId + "-" + position);
trailPosition.setSnowMachineStatus(1);
trailPosition.setSnowMachineId(snowMachineDevice.getId());
// 雪道位置状态信息
TrailPositionMonitorInfo trailPositionMonitorInfo = new TrailPositionMonitorInfo();
trailPositionMonitorInfo.setTrailPosition(trailPosition);
trailPositionMonitorInfo.setSnowMakerName(snowMachineDevice.getName());
trailPositionMonitorInfo.setPriority(1);
trailPositionMonitorInfo.setEnvironmentTemperature(-3.5);
trailPositionMonitorInfo.setEnvironmentHumidity(50.0);
trailPositionMonitorInfo.setWetBulbTemperature(0.5);
trailPositionMonitorInfo.setCommunicationStatus(true);
trailPositionMonitorInfo.setIsNormal(true);
trailPositionMonitorInfo.setIsRunning(true);
trailPositionMonitorInfo.setTemperatureConditionSatisfied(true);
trailPositionMonitorInfo.setWindSpeed(5.0);
trailPositionMonitorInfo.setWindDirection(180.0);
// 造雪机设备状态
SnowMachineDeviceInfo snowMachineDeviceInfo = new SnowMachineDeviceInfo();
snowMachineDeviceInfo.setSnowMachineDevice(snowMachineDevice);
snowMachineDeviceInfo.setFrontWaterPressure(0.5 + Math.random() * 0.3); // 前端水压 0.5-0.8 MPa
snowMachineDeviceInfo.setBackWaterPressure(0.4 + Math.random() * 0.2); // 后端水压 0.4-0.6 MPa
snowMachineDeviceInfo.setPressure(0.8 + Math.random() * 0.2); // 气压 0.8-1.0 MPa
snowMachineDeviceInfo.setTemperature(2.5 + Math.random() * 2.0); // 水温 2.5-4.5 ℃
snowMachineDeviceInfo.setGivenAngle(45.0 + Math.random() * 10.0); // 给定开度 45-55°
snowMachineDeviceInfo.setActualAngle(44.0 + Math.random() * 12.0); // 实际开度 44-56°
snowMachineDeviceInfo.setIsNormal(Math.random() > 0.1); // 是否正常 90%概率正常
snowMachineDeviceInfo.setMode((int)(Math.random() * 3) + 1); // 模式 1-3随机
snowMachineDeviceInfo.setCompressorStatus((int)(Math.random() * 2) + 1); // 空压机状态 1-2随机
snowMachineDeviceInfo.setFanStatus((int)(Math.random() * 2) + 1); // 风机状态 1-2随机
snowMachineDeviceInfo.setHeatingRingStatus((int)(Math.random() * 2) + 1); // 加热环状态 1-2随机
snowMachineDeviceInfo.setValveStatus((int)(Math.random() * 2) + 1); // 电磁阀状态1 1-2随机
snowMachineDeviceInfo.setValveStatus2((int)(Math.random() * 2) + 1); // 电磁阀状态2 1-2随机
snowMachineDeviceInfo.setValveStatus3((int)(Math.random() * 2) + 1); // 电磁阀状态3 1-2随机
snowMachineDeviceInfo.setPitchMode((int)(Math.random() * 3) + 1); // 俯仰模式 1-3随机
snowMachineDeviceInfo.setPitchAngle(15.0 + Math.random() * 20.0); // 俯仰角度 15-35°
snowMachineDeviceInfo.setPitchStatus((int)(Math.random() * 2) + 1); // 俯仰状态 1-2随机
snowMachineDeviceInfo.setYawMode((int)(Math.random() * 3) + 1); // 摆头模式 1-3随机
snowMachineDeviceInfo.setYawAngle(30.0 + Math.random() * 40.0); // 摆头角度 30-70°
snowMachineDeviceInfo.setYawStatus((int)(Math.random() * 2) + 1); // 摆头状态 1-2随机
// 造雪机配置
SnowMachineDeviceParams snowMakerDeviceParams = new SnowMachineDeviceParams();
snowMakerDeviceParams.setWorkMode((int)(Math.random() * 3) + 1); // 工作模式 1-3随机
snowMakerDeviceParams.setPriority((int)(Math.random() * 5) + 1); // 优先级 1-5随机
snowMakerDeviceParams.setSnowQuality((int)(Math.random() * 5) + 1); // 雪质 1-5随机
snowMakerDeviceParams.setStartTemperature(-5.0 + Math.random() * 10.0); // 启动温度 -5.0 ~ 5.0
snowMakerDeviceParams.setStopTemperature(-5.0 + Math.random() * 10.0); // 停止温度 -5.0 ~ 5.0
snowMakerDeviceParams.setFlowAdjustment((int)(Math.random() * 50)); // 流量调节 0 ~ 50
// 数据统计
TrailPositionStatisticsInfo trailPositionStatisticsInfo = new TrailPositionStatisticsInfo();
trailPositionStatisticsInfo.setRunningDuration(120.5 + Math.random() * 100.0); // 运行时长 120.5-220.5分钟
trailPositionStatisticsInfo.setFlowStatistics(1000.0 + Math.random() * 500.0); // 流量统计 1000-1500 L/H
trailPositionStatisticsInfo.setSnowArea(500.0 + Math.random() * 300.0); // 造雪面积 500-800 平方米
result.setTrailPositionMonitorInfo(trailPositionMonitorInfo);
result.setSnowMakerInfo(snowMachineDeviceInfo);
result.setSnowMakerDeviceParams(snowMakerDeviceParams);
result.setTrailPositionStatisticsInfo(trailPositionStatisticsInfo);
return responseData.success(result);
}
@PostMapping("/connectDevice")
@Operation(summary = "雪道造雪机(上机)")
public HttpResponseData<Boolean> connectDevice(Integer trailPositionId, Integer deviceId) {
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
return responseData.success(trailPositionService.connectDevice(trailPositionId, deviceId));
}
@PostMapping("/disconnectDevice")
@Operation(summary = "雪道造雪机(下机)")
public HttpResponseData<Boolean> disconnectDevice(Integer trailPositionId) {
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
return responseData.success(trailPositionService.disconnectDevice(trailPositionId));
}
@PostMapping("/groupControl")
@Operation(summary = "雪道造雪机(群控)")
public HttpResponseData<Boolean> groupControl(@RequestBody GroupControlRequest request) {
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
return responseData.success(trailPositionService.groupControl(request.getTrailPositionList(), request.getParams()));
}
// 俯仰水平控制
@PostMapping("/pitchHorizontalControl")
@Operation(summary = "雪道造雪机俯仰水平控制")
public HttpResponseData<Boolean> pitchHorizontalControl(@RequestBody PitchHorizontalControlRequest request) {
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
return responseData.success(trailPositionService.pitchHorizontalControl(request.getTrailPosition(), request.getParams()));
}
@PostMapping("/saveSnowMakerDeviceParams")
@Operation(summary = "保存造雪机参数")
public HttpResponseData<Boolean> groupControl(@RequestBody GroupControlSingleRequest request) {
HttpResponseData<Boolean> responseData = new HttpResponseData<>();
return responseData.success(trailPositionService.saveSnowMakerDeviceParams(request.getTrailPosition(), request.getParams()));
}
@Data
public static class GroupControlRequest {
private List<Integer> trailPositionList;
private SnowMachineDeviceParams params;
}
@Data
public static class GroupControlSingleRequest {
private Integer trailPosition;
private SnowMachineDeviceParams params;
}
@Data
public static class PitchHorizontalControlRequest {
private Integer trailPosition;
private SnowMachineDevicePitchHorizontalParams params;
}
}

View File

@@ -1,10 +1,12 @@
package com.ski.lichuan.admin.filter;
import com.ski.lichuan.common.utils.JwtUtils;
import com.ski.lichuan.model.auth.SysUser;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -15,6 +17,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
@@ -36,6 +39,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
// 2. 验证 Token 并获取用户名
if (jwtUtils.validateToken(token)) {
// 鉴权通过,从 Token 中获取用户名
String username = jwtUtils.getUsernameFromToken(token);
// 3. 加载用户信息并设置认证状态
UserDetails userDetails = userDetailsService.loadUserByUsername(username);

View File

@@ -0,0 +1,21 @@
spring.application.name=ski-dashboard-admin
server.port=8080
# postgresql
spring.datasource.url=jdbc:postgresql://localhost:5432/ski_dashboard
spring.datasource.username=postgres
spring.datasource.password=tanlifan
# Spring Session
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
spring.session.jdbc.table-name=SPRING_SESSION
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
# Logging levels for development
logging.level.com.ski.lichuan=DEBUG
logging.level.org.springframework.web=DEBUG
logging.level.org.mybatis=DEBUG

View File

@@ -0,0 +1,21 @@
spring.application.name=ski-dashboard-admin
server.port=8080
# postgresql
spring.datasource.url=jdbc:postgresql://localhost:8081/ski_dashboard
spring.datasource.username=postgres
spring.datasource.password=postgres
# Spring Session
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
spring.session.jdbc.table-name=SPRING_SESSION
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
# Logging levels for production
logging.level.com.ski.lichuan=INFO
logging.level.org.springframework.web=WARN
logging.level.org.mybatis=WARN

View File

@@ -1,13 +1,16 @@
spring.application.name=ski-dashboard-admin
# ??????? postgresql
spring.datasource.url=jdbc:postgresql://localhost:5432/ski_dashboard
spring.datasource.username=postgres
spring.datasource.password=tanlifan
spring.profiles.active=prod
# Spring Session??
# Spring Session
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
spring.session.jdbc.table-name=SPRING_SESSION
JWT_SECRET=vf4JZhcyfdK7tJs0GZ3Qjf0dSv4BId9ITjsM2fol26gOBxM17nUySiMcV0Lo2u0Y
# MyBatis configuration - enable camel case mapping
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath*:mapper/*.xml
thingsboard.client.url=https://tb.ski.bkiiot.com
thingsboard.client.username=tenant@thingsboard.org
thingsboard.client.password=tenant

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 定义日志文件的存储路径 -->
<property name="LOG_HOME" value="logs" />
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- INFO级别的日志输出到 info.log -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- ERROR级别的日志输出到 error.log -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 根日志配置 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>