feat(core): 增强文件上传配置和异常处理
- 配置文件上传大小限制,单个文件最大10MB,请求最大50MB - 添加文件写入磁盘阈值配置,超过2MB写入临时文件 - 实现文件上传超限异常处理,返回友好提示信息 - 优化应用启动日志,显示访问地址和运行环境信息 - 增加支付订单查询和更新的日志记录 - 创建阿里云OSS配置属性类,统一管理OSS参数 - 添加业务异常类,支持自定义错误码和消息 - 完善系统架构文档,描述前后端包结构和核心组件 - 新增商品创建请求DTO,支持SKU列表和校验规则 - 添加风控相关的客户信息和商品信息DTO - 配置Logback日志框架,支持不同环境的日志输出策略
This commit is contained in:
179
mt-pay/ARCHITECTURE_COMPLETE.md
Normal file
179
mt-pay/ARCHITECTURE_COMPLETE.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 系统架构完整性说明
|
||||
|
||||
## 后端架构(mt-pay)
|
||||
|
||||
### 1. 包结构
|
||||
|
||||
```
|
||||
com.mtkj.mtpay/
|
||||
├── common/ # 通用组件
|
||||
│ ├── Result.java # 统一响应结果类
|
||||
│ ├── ResultCode.java # 响应码枚举
|
||||
│ ├── constants/ # 常量类
|
||||
│ │ └── PaymentConstants.java
|
||||
│ └── enums/ # 枚举类
|
||||
│ ├── OrderStatus.java
|
||||
│ ├── PaymentType.java
|
||||
│ └── RecordType.java
|
||||
├── config/ # 配置类
|
||||
│ ├── DruidDataSourceConfig.java
|
||||
│ ├── MyBatisPlusConfig.java
|
||||
│ ├── MyMetaObjectHandler.java
|
||||
│ ├── PingPongProperties.java
|
||||
│ ├── RestClientConfig.java
|
||||
│ └── WebConfig.java # Web配置(跨域等)
|
||||
├── controller/ # 控制器层
|
||||
│ ├── PaymentController.java
|
||||
│ └── CallbackController.java
|
||||
├── dto/ # 数据传输对象
|
||||
│ ├── request/
|
||||
│ ├── response/
|
||||
│ └── risk/
|
||||
├── entity/ # 实体类
|
||||
│ ├── PaymentOrder.java
|
||||
│ └── PaymentRecord.java
|
||||
├── exception/ # 异常处理
|
||||
│ ├── BusinessException.java
|
||||
│ └── GlobalExceptionHandler.java
|
||||
├── mapper/ # 数据访问层
|
||||
│ ├── PaymentOrderMapper.java
|
||||
│ └── PaymentRecordMapper.java
|
||||
├── service/ # 服务层(接口)
|
||||
│ ├── SignatureService.java
|
||||
│ ├── PingPongPayService.java
|
||||
│ ├── PaymentOrderService.java
|
||||
│ └── CallbackService.java
|
||||
├── service/impl/ # 服务层(实现)
|
||||
│ ├── SignatureServiceImpl.java
|
||||
│ ├── PingPongPayServiceImpl.java
|
||||
│ ├── PaymentOrderServiceImpl.java
|
||||
│ └── CallbackServiceImpl.java
|
||||
└── util/ # 工具类
|
||||
├── DateUtils.java
|
||||
├── StringUtils.java
|
||||
└── OrderIdGenerator.java
|
||||
```
|
||||
|
||||
### 2. 核心组件说明
|
||||
|
||||
#### 统一响应格式
|
||||
- **Result<T>**: 统一响应结果类,所有接口返回统一格式
|
||||
- **ResultCode**: 响应码枚举,定义所有业务响应码
|
||||
|
||||
#### 异常处理
|
||||
- **BusinessException**: 业务异常类
|
||||
- **GlobalExceptionHandler**: 全局异常处理器,统一处理异常
|
||||
|
||||
#### 枚举类
|
||||
- **OrderStatus**: 订单状态枚举
|
||||
- **PaymentType**: 支付类型枚举
|
||||
- **RecordType**: 记录类型枚举
|
||||
|
||||
#### 工具类
|
||||
- **DateUtils**: 日期时间工具类
|
||||
- **StringUtils**: 字符串工具类
|
||||
- **OrderIdGenerator**: 订单号生成器
|
||||
|
||||
#### 常量类
|
||||
- **PaymentConstants**: 支付相关常量
|
||||
|
||||
#### 配置类
|
||||
- **WebConfig**: Web配置(跨域、拦截器等)
|
||||
|
||||
## 前端架构(MTKJPAY-FRONT)
|
||||
|
||||
### 1. 目录结构
|
||||
|
||||
```
|
||||
MTKJPAY-FRONT/
|
||||
├── src/
|
||||
│ ├── api/ # API接口
|
||||
│ │ ├── request.js # Axios封装
|
||||
│ │ └── payment.js # 支付相关API
|
||||
│ ├── components/ # 通用组件
|
||||
│ │ ├── PageHeader.vue
|
||||
│ │ └── Loading.vue
|
||||
│ ├── config/ # 配置文件
|
||||
│ │ └── index.js
|
||||
│ ├── router/ # 路由配置
|
||||
│ │ └── index.js
|
||||
│ ├── store/ # 状态管理
|
||||
│ │ └── index.js
|
||||
│ ├── utils/ # 工具函数
|
||||
│ │ ├── constants.js # 常量定义
|
||||
│ │ ├── helpers.js # 工具函数
|
||||
│ │ └── request.js # 请求工具
|
||||
│ ├── views/ # 页面组件
|
||||
│ │ ├── CreateOrder.vue
|
||||
│ │ ├── Checkout.vue
|
||||
│ │ ├── PaymentResult.vue
|
||||
│ │ └── OrderQuery.vue
|
||||
│ ├── App.vue # 根组件
|
||||
│ └── main.js # 入口文件
|
||||
├── .env.development # 开发环境配置
|
||||
├── .env.production # 生产环境配置
|
||||
└── vite.config.js # Vite配置
|
||||
```
|
||||
|
||||
### 2. 核心组件说明
|
||||
|
||||
#### 工具类
|
||||
- **constants.js**: 常量定义(订单状态、支付类型、币种等)
|
||||
- **helpers.js**: 工具函数(格式化、验证、防抖节流等)
|
||||
- **request.js**: 请求工具函数
|
||||
|
||||
#### 通用组件
|
||||
- **PageHeader.vue**: 页面头部组件
|
||||
- **Loading.vue**: 加载组件
|
||||
|
||||
#### 配置管理
|
||||
- **config/index.js**: 统一配置管理
|
||||
- **.env.development**: 开发环境配置
|
||||
- **.env.production**: 生产环境配置
|
||||
|
||||
#### 状态管理
|
||||
- **store/index.js**: 简单状态管理(可扩展为Pinia)
|
||||
|
||||
## 架构特点
|
||||
|
||||
### 1. 分层清晰
|
||||
- Controller → Service → Mapper → Entity
|
||||
- 接口与实现分离
|
||||
- DTO与Entity分离
|
||||
|
||||
### 2. 统一规范
|
||||
- 统一响应格式(Result)
|
||||
- 统一异常处理
|
||||
- 统一响应码
|
||||
|
||||
### 3. 可扩展性
|
||||
- 枚举类便于扩展
|
||||
- 工具类可复用
|
||||
- 组件化设计
|
||||
|
||||
### 4. 可维护性
|
||||
- 代码结构清晰
|
||||
- 命名规范统一
|
||||
- 注释完整
|
||||
|
||||
### 5. 完整性
|
||||
- 包含工具类、常量、枚举
|
||||
- 包含异常处理、统一响应
|
||||
- 包含配置管理、状态管理
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **统一响应格式**: 所有接口使用Result<T>返回
|
||||
2. **异常处理**: 使用BusinessException抛出业务异常
|
||||
3. **枚举使用**: 使用枚举替代魔法字符串
|
||||
4. **工具类**: 通用功能封装为工具类
|
||||
5. **配置管理**: 配置统一管理,支持多环境
|
||||
|
||||
## 扩展建议
|
||||
|
||||
1. **日志切面**: 添加AOP日志切面
|
||||
2. **接口文档**: 集成Swagger/OpenAPI
|
||||
3. **缓存**: 添加Redis缓存支持
|
||||
4. **消息队列**: 添加消息队列支持
|
||||
5. **监控**: 添加系统监控和链路追踪
|
||||
|
||||
@@ -1,13 +1,42 @@
|
||||
package com.mtkj.mtpay;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
public class MtPayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MtPayApplication.class, args);
|
||||
try {
|
||||
SpringApplication app = new SpringApplication(MtPayApplication.class);
|
||||
Environment env = app.run(args).getEnvironment();
|
||||
|
||||
String applicationName = env.getProperty("spring.application.name", "mt-pay");
|
||||
String serverPort = env.getProperty("server.port", "8080");
|
||||
String contextPath = env.getProperty("server.servlet.context-path", "");
|
||||
String activeProfiles = String.join(",", env.getActiveProfiles());
|
||||
|
||||
log.info("""
|
||||
|
||||
========================================
|
||||
应用启动成功!
|
||||
========================================
|
||||
应用名称: {}
|
||||
运行环境: {}
|
||||
访问地址: http://localhost:{}{}
|
||||
========================================
|
||||
""",
|
||||
applicationName,
|
||||
activeProfiles.isEmpty() ? "default" : activeProfiles,
|
||||
serverPort,
|
||||
contextPath);
|
||||
} catch (Exception e) {
|
||||
log.error("应用启动失败", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.mtkj.mtpay.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 阿里云OSS配置属性
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "aliyun.oss")
|
||||
public class AliyunOSSProperties {
|
||||
|
||||
/**
|
||||
* AccessKeyId
|
||||
*/
|
||||
private String accessId;
|
||||
|
||||
/**
|
||||
* AccessKeySecret
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Endpoint(地域节点)
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* Bucket名称
|
||||
*/
|
||||
private String bucketName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.mtkj.mtpay.dto.request;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建商品请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class CreateProductRequestDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@NotBlank(message = "商品名称不能为空")
|
||||
@Size(max = 255, message = "商品名称长度不能超过255")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 商品价格(基础价格)
|
||||
*/
|
||||
@NotNull(message = "商品价格不能为空")
|
||||
private BigDecimal price;
|
||||
|
||||
/**
|
||||
* 主图URL
|
||||
*/
|
||||
@Size(max = 4000, message = "主图URL长度不能超过4000")
|
||||
private String mainImage;
|
||||
|
||||
/**
|
||||
* 商品状态:ACTIVE-上架,INACTIVE-下架
|
||||
*/
|
||||
private String status = "ACTIVE";
|
||||
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
@NotNull(message = "店铺ID不能为空")
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* SKU列表
|
||||
*/
|
||||
@Valid
|
||||
@NotNull(message = "SKU列表不能为空")
|
||||
@Size(min = 1, message = "至少需要一个SKU")
|
||||
private List<CreateProductSkuDTO> skus;
|
||||
|
||||
/**
|
||||
* SKU DTO
|
||||
*/
|
||||
@Data
|
||||
public static class CreateProductSkuDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* SKU编码
|
||||
*/
|
||||
@NotBlank(message = "SKU编码不能为空")
|
||||
@Size(max = 2000, message = "SKU编码长度不能超过2000")
|
||||
private String sku;
|
||||
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
@NotNull(message = "SKU价格不能为空")
|
||||
private BigDecimal price;
|
||||
|
||||
/**
|
||||
* 货币(ISO 4217三位币种代码)
|
||||
*/
|
||||
@NotBlank(message = "货币不能为空")
|
||||
@Size(min = 3, max = 3, message = "货币必须为3位ISO 4217代码")
|
||||
private String currency = "USD";
|
||||
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
private Integer stock = 0;
|
||||
|
||||
/**
|
||||
* 销售属性(JSON格式)
|
||||
*/
|
||||
private String salesAttrs;
|
||||
|
||||
/**
|
||||
* SKU图片URL
|
||||
*/
|
||||
@Size(max = 4000, message = "SKU图片URL长度不能超过4000")
|
||||
private String skuImage;
|
||||
|
||||
/**
|
||||
* 重量(单位:克)
|
||||
*/
|
||||
private BigDecimal weight;
|
||||
|
||||
/**
|
||||
* 大小/尺寸(JSON格式)
|
||||
*/
|
||||
@Size(max = 200, message = "尺寸JSON长度不能超过200")
|
||||
private String size;
|
||||
|
||||
/**
|
||||
* 规格(文本描述)
|
||||
*/
|
||||
@Size(max = 2000, message = "规格长度不能超过2000")
|
||||
private String specification;
|
||||
|
||||
/**
|
||||
* SKU状态:ACTIVE-启用,INACTIVE-禁用
|
||||
*/
|
||||
private String status = "ACTIVE";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.mtkj.mtpay.dto.risk;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 客户信息DTO
|
||||
*/
|
||||
@Data
|
||||
public class CustomerDTO implements Serializable {
|
||||
|
||||
private String customerId;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String email;
|
||||
|
||||
private String domain;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String mobile;
|
||||
|
||||
private String workPhone;
|
||||
|
||||
private String identificationType;
|
||||
|
||||
private String identificationId;
|
||||
|
||||
private String registerTime;
|
||||
|
||||
private String registerIp;
|
||||
|
||||
private String registerTerminal;
|
||||
|
||||
private String registerCountry;
|
||||
|
||||
private String registerRange;
|
||||
|
||||
private String orderTime;
|
||||
|
||||
private String orderIp;
|
||||
|
||||
private String orderCountry;
|
||||
|
||||
private String payIp;
|
||||
|
||||
private String payCountry;
|
||||
|
||||
private String loginTime;
|
||||
|
||||
private String loginIp;
|
||||
|
||||
private String lastPayTime;
|
||||
|
||||
private String acquisitionChannel;
|
||||
|
||||
private String firstOrder;
|
||||
|
||||
private String nonMemberOrder;
|
||||
|
||||
private String preferentialOrder;
|
||||
|
||||
private String birthDate;
|
||||
|
||||
private String customerStatus;
|
||||
}
|
||||
|
||||
27
mt-pay/src/main/java/com/mtkj/mtpay/dto/risk/GoodsDTO.java
Normal file
27
mt-pay/src/main/java/com/mtkj/mtpay/dto/risk/GoodsDTO.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.mtkj.mtpay.dto.risk;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 商品信息DTO
|
||||
*/
|
||||
@Data
|
||||
public class GoodsDTO implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private String sku;
|
||||
|
||||
private String averageUnitPrice;
|
||||
|
||||
private String number;
|
||||
|
||||
private String virtualProduct;
|
||||
|
||||
private String imgUrl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.mtkj.mtpay.exception;
|
||||
|
||||
import com.mtkj.mtpay.common.ResultCode;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private final String code;
|
||||
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
this.code = ResultCode.FAIL.getCode();
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BusinessException(ResultCode resultCode) {
|
||||
super(resultCode.getMessage());
|
||||
this.code = resultCode.getCode();
|
||||
}
|
||||
|
||||
public BusinessException(ResultCode resultCode, String message) {
|
||||
super(message);
|
||||
this.code = resultCode.getCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -45,6 +46,17 @@ public class GlobalExceptionHandler {
|
||||
.body(Result.fail(ResultCode.VALIDATION_ERROR.getCode(), ResultCode.VALIDATION_ERROR.getMessage(), errors));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理文件上传大小超限异常
|
||||
*/
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public ResponseEntity<Result<Object>> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.warn("文件上传大小超限: {}", e.getMessage());
|
||||
String message = "文件大小超过限制,单个文件最大10MB,请压缩后重试";
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Result.fail(ResultCode.PARAM_ERROR.getCode(), message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理运行时异常
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,7 @@ public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||||
request.getMerchantTransactionId()
|
||||
);
|
||||
if (existingOrder.isPresent()) {
|
||||
log.warn("订单号已存在,商户订单号: {}", request.getMerchantTransactionId());
|
||||
throw new BusinessException(ResultCode.ORDER_EXISTS);
|
||||
}
|
||||
|
||||
@@ -93,29 +94,49 @@ public class PaymentOrderServiceImpl implements PaymentOrderService {
|
||||
|
||||
@Override
|
||||
public Optional<PaymentOrder> findByMerchantTransactionId(String merchantTransactionId) {
|
||||
return paymentOrderMapper.findByMerchantTransactionId(merchantTransactionId);
|
||||
log.debug("查询支付订单,商户订单号: {}", merchantTransactionId);
|
||||
Optional<PaymentOrder> order = paymentOrderMapper.findByMerchantTransactionId(merchantTransactionId);
|
||||
if (order.isPresent()) {
|
||||
log.debug("找到支付订单,商户订单号: {}, 订单状态: {}", merchantTransactionId, order.get().getStatus());
|
||||
} else {
|
||||
log.debug("未找到支付订单,商户订单号: {}", merchantTransactionId);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PaymentOrder> findByTransactionId(String transactionId) {
|
||||
return paymentOrderMapper.findByTransactionId(transactionId);
|
||||
log.debug("查询支付订单,PingPong交易流水号: {}", transactionId);
|
||||
Optional<PaymentOrder> order = paymentOrderMapper.findByTransactionId(transactionId);
|
||||
if (order.isPresent()) {
|
||||
log.debug("找到支付订单,PingPong交易流水号: {}, 订单状态: {}", transactionId, order.get().getStatus());
|
||||
} else {
|
||||
log.debug("未找到支付订单,PingPong交易流水号: {}", transactionId);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public PaymentOrder updateOrderStatus(String merchantTransactionId, String status, String transactionId) {
|
||||
log.info("更新订单状态,商户订单号: {}, 新状态: {}, PingPong交易流水号: {}",
|
||||
merchantTransactionId, status, transactionId);
|
||||
Optional<PaymentOrder> orderOpt = paymentOrderMapper.findByMerchantTransactionId(merchantTransactionId);
|
||||
if (orderOpt.isEmpty()) {
|
||||
log.warn("订单不存在,无法更新状态,商户订单号: {}", merchantTransactionId);
|
||||
throw new BusinessException(ResultCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
|
||||
PaymentOrder order = orderOpt.get();
|
||||
String oldStatus = order.getStatus();
|
||||
order.setStatus(status);
|
||||
if (transactionId != null && !transactionId.isEmpty()) {
|
||||
order.setTransactionId(transactionId);
|
||||
}
|
||||
|
||||
paymentOrderMapper.updateById(order);
|
||||
log.info("订单状态更新成功,商户订单号: {}, 原状态: {}, 新状态: {}",
|
||||
merchantTransactionId, oldStatus, status);
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,16 @@ pingpong:
|
||||
# 服务器配置
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /
|
||||
# 文件上传配置
|
||||
multipart:
|
||||
# 单个文件最大大小(10MB)
|
||||
max-file-size: 10MB
|
||||
# 请求最大大小(50MB,支持多文件上传)
|
||||
max-request-size: 50MB
|
||||
# 文件写入磁盘的阈值(超过此大小会写入临时文件)
|
||||
file-size-threshold: 2MB
|
||||
|
||||
# 阿里云OSS相关配置
|
||||
aliyun:
|
||||
@@ -80,6 +90,4 @@ aliyun:
|
||||
accessKey: sAQR2swByBgmMOofH97hSJT638aVcJ
|
||||
endpoint: https://oss-cn-hangzhou.aliyuncs.com
|
||||
bucketName: mtkj2025
|
||||
servlet:
|
||||
context-path: /
|
||||
|
||||
|
||||
119
mt-pay/src/main/resources/logback-spring.xml
Normal file
119
mt-pay/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,119 @@
|
||||
<?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>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 按照每天生成日志文件 -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件输出的文件名 -->
|
||||
<FileNamePattern>${LOG_HOME}/mt-pay.%d{yyyy-MM-dd}.log</FileNamePattern>
|
||||
<!-- 日志文件保留天数 -->
|
||||
<MaxHistory>30</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<!-- 日志文件最大的大小 -->
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<MaxFileSize>10MB</MaxFileSize>
|
||||
</triggeringPolicy>
|
||||
</appender>
|
||||
|
||||
<!-- 错误日志文件 -->
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<FileNamePattern>${LOG_HOME}/mt-pay-error.%d{yyyy-MM-dd}.log</FileNamePattern>
|
||||
<MaxHistory>30</MaxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<MaxFileSize>10MB</MaxFileSize>
|
||||
</triggeringPolicy>
|
||||
<!-- 此日志文件只记录ERROR级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 异步输出 -->
|
||||
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<!-- 不丢失日志,默认如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
|
||||
<discardingThreshold>0</discardingThreshold>
|
||||
<!-- 更改默认的队列的深度,该值会影响性能,默认值为256 -->
|
||||
<queueSize>512</queueSize>
|
||||
<appender-ref ref="FILE"/>
|
||||
</appender>
|
||||
|
||||
<!-- 异步输出错误日志 -->
|
||||
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<discardingThreshold>0</discardingThreshold>
|
||||
<queueSize>512</queueSize>
|
||||
<appender-ref ref="ERROR_FILE"/>
|
||||
</appender>
|
||||
|
||||
<!-- 开发环境:控制台和文件都输出 -->
|
||||
<springProfile name="dev">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ASYNC_FILE"/>
|
||||
<appender-ref ref="ASYNC_ERROR_FILE"/>
|
||||
</root>
|
||||
<!-- 项目包路径,控制日志级别 -->
|
||||
<logger name="com.mtkj.mtpay" level="DEBUG"/>
|
||||
<!-- MyBatis SQL日志 -->
|
||||
<logger name="com.mtkj.mtpay.mapper" level="DEBUG"/>
|
||||
</springProfile>
|
||||
|
||||
<!-- 测试环境:只输出文件 -->
|
||||
<springProfile name="test">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="ASYNC_FILE"/>
|
||||
<appender-ref ref="ASYNC_ERROR_FILE"/>
|
||||
</root>
|
||||
<logger name="com.mtkj.mtpay" level="INFO"/>
|
||||
</springProfile>
|
||||
|
||||
<!-- 生产环境:只输出文件,日志级别为INFO -->
|
||||
<springProfile name="prod">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="ASYNC_FILE"/>
|
||||
<appender-ref ref="ASYNC_ERROR_FILE"/>
|
||||
</root>
|
||||
<logger name="com.mtkj.mtpay" level="INFO"/>
|
||||
<!-- 生产环境关闭MyBatis SQL日志 -->
|
||||
<logger name="com.mtkj.mtpay.mapper" level="WARN"/>
|
||||
</springProfile>
|
||||
|
||||
<!-- 默认配置 -->
|
||||
<springProfile name="!dev & !test & !prod">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ASYNC_FILE"/>
|
||||
<appender-ref ref="ASYNC_ERROR_FILE"/>
|
||||
</root>
|
||||
<logger name="com.mtkj.mtpay" level="INFO"/>
|
||||
</springProfile>
|
||||
|
||||
<!-- 第三方框架日志级别 -->
|
||||
<logger name="org.springframework" level="WARN"/>
|
||||
<logger name="org.mybatis" level="WARN"/>
|
||||
<logger name="com.alibaba.druid" level="WARN"/>
|
||||
<logger name="com.aliyun.oss" level="WARN"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
Reference in New Issue
Block a user