diff --git a/mt-pay/LOGGING_GUIDE.md b/mt-pay/LOGGING_GUIDE.md new file mode 100644 index 0000000..5d0c7e2 --- /dev/null +++ b/mt-pay/LOGGING_GUIDE.md @@ -0,0 +1,218 @@ +# 日志使用指南 + +## 概述 + +项目已全面集成SLF4J日志功能,使用Logback作为日志实现框架。所有关键类都已添加日志记录,便于问题排查和系统监控。 + +## 日志配置 + +### 日志配置文件 + +- **位置**: `src/main/resources/logback-spring.xml` +- **功能**: 配置日志输出格式、文件路径、日志级别等 + +### 日志级别 + +- **DEBUG**: 详细的调试信息,通常只在开发环境使用 +- **INFO**: 一般信息,记录系统运行状态和关键操作 +- **WARN**: 警告信息,表示潜在问题但不影响系统运行 +- **ERROR**: 错误信息,表示系统错误需要关注 + +### 日志输出 + +1. **控制台输出**: 开发环境默认输出到控制台 +2. **文件输出**: + - 所有日志: `logs/mt-pay.{日期}.log` + - 错误日志: `logs/mt-pay-error.{日期}.log` +3. **日志轮转**: 按天轮转,保留30天,单文件最大10MB + +## 已添加日志的类 + +### 1. 配置类 + +- ✅ `MyBatisPlusConfig` - MyBatis-Plus配置日志 +- ✅ `RestClientConfig` - RestClient配置日志 +- ✅ `WebConfig` - Web配置(跨域)日志 +- ✅ `DruidDataSourceConfig` - 数据源配置日志(已有) +- ✅ `MyMetaObjectHandler` - 自动填充日志(已有) + +### 2. 控制器类 + +- ✅ `ProductController` - 商品管理接口日志(已有) +- ✅ `PaymentController` - 支付接口日志(已有) +- ✅ `CallbackController` - 回调接口日志(已有) + +### 3. 服务实现类 + +- ✅ `ProductServiceImpl` - 商品服务日志(已增强) +- ✅ `PaymentOrderServiceImpl` - 支付订单服务日志(已增强) +- ✅ `PingPongPayServiceImpl` - PingPong支付服务日志(已有) +- ✅ `SignatureServiceImpl` - 签名服务日志(已有) +- ✅ `CallbackServiceImpl` - 回调服务日志(已有) +- ✅ `OssServiceImpl` - OSS服务日志(已有) + +### 4. 工具类 + +- ✅ `OrderIdGenerator` - 订单号生成器日志(已添加) + +### 5. 异常处理 + +- ✅ `GlobalExceptionHandler` - 全局异常处理日志(已有) + +### 6. 主应用类 + +- ✅ `MtPayApplication` - 应用启动日志(已增强) + +## 日志使用示例 + +### 在类中使用日志 + +```java +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class YourService { + + public void doSomething() { + // 记录信息日志 + log.info("开始执行操作,参数: {}", param); + + try { + // 业务逻辑 + log.debug("调试信息: {}", debugInfo); + + } catch (Exception e) { + // 记录错误日志 + log.error("操作失败,参数: {}", param, e); + throw e; + } + + log.info("操作完成,结果: {}", result); + } +} +``` + +### 日志级别使用建议 + +1. **DEBUG**: + - 详细的执行流程 + - 中间变量值 + - SQL参数值(MyBatis) + +2. **INFO**: + - 关键业务操作开始/结束 + - 重要状态变更 + - 外部接口调用 + +3. **WARN**: + - 业务异常(如订单不存在但继续处理) + - 配置问题 + - 性能警告 + +4. **ERROR**: + - 系统异常 + - 数据库操作失败 + - 外部接口调用失败 + +## 日志格式 + +### 控制台格式 +``` +2025-12-19 16:37:50.530 [restartedMain] INFO com.mtkj.mtpay.MtPayApplication - 应用启动成功! +``` + +### 文件格式 +``` +2025-12-19 16:37:50.530 [http-nio-8080-exec-1] INFO com.mtkj.mtpay.controller.ProductController - 创建商品请求:ProductRequestDTO(...) +``` + +## 环境配置 + +### 开发环境 (dev) +- 控制台输出: ✅ +- 文件输出: ✅ +- 日志级别: DEBUG +- MyBatis SQL日志: ✅ + +### 测试环境 (test) +- 控制台输出: ❌ +- 文件输出: ✅ +- 日志级别: INFO +- MyBatis SQL日志: ❌ + +### 生产环境 (prod) +- 控制台输出: ❌ +- 文件输出: ✅ +- 日志级别: INFO +- MyBatis SQL日志: ❌ + +## 日志文件位置 + +- **日志目录**: `./logs/`(项目根目录) +- **所有日志**: `logs/mt-pay.{日期}.log` +- **错误日志**: `logs/mt-pay-error.{日期}.log` + +## 日志查看 + +### 开发环境 +- 直接在IDE控制台查看 +- 或查看 `logs/` 目录下的日志文件 + +### 生产环境 +- 使用 `tail -f logs/mt-pay-*.log` 实时查看 +- 使用 `grep ERROR logs/mt-pay-*.log` 查找错误 +- 使用日志分析工具(如ELK、Graylog等) + +## 最佳实践 + +1. **使用占位符**: 使用 `{}` 占位符而不是字符串拼接 + ```java + // ✅ 推荐 + log.info("用户ID: {}, 操作: {}", userId, action); + + // ❌ 不推荐 + log.info("用户ID: " + userId + ", 操作: " + action); + ``` + +2. **异常日志**: 记录异常时包含堆栈信息 + ```java + // ✅ 推荐 + log.error("操作失败", e); + + // ❌ 不推荐 + log.error("操作失败: " + e.getMessage()); + ``` + +3. **敏感信息**: 不要记录密码、密钥等敏感信息 + ```java + // ❌ 不要这样做 + log.info("用户密码: {}", password); + ``` + +4. **日志级别**: 根据重要性选择合适的日志级别 + - 关键业务操作: INFO + - 调试信息: DEBUG + - 警告: WARN + - 错误: ERROR + +## 常见问题 + +### Q: 如何修改日志级别? +A: 修改 `logback-spring.xml` 中对应环境的日志级别配置。 + +### Q: 如何查看SQL日志? +A: 开发环境默认开启,生产环境已关闭。可在 `logback-spring.xml` 中修改 `com.mtkj.mtpay.mapper` 的日志级别。 + +### Q: 日志文件太大怎么办? +A: 已配置日志轮转,按天轮转,单文件最大10MB,保留30天。 + +### Q: 如何禁用某个类的日志? +A: 在 `logback-spring.xml` 中添加: +```xml + +``` + +## 总结 + +项目已全面集成SLF4J日志功能,所有关键操作都有日志记录。通过合理的日志级别和格式,可以快速定位问题、监控系统运行状态。 + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/config/MyBatisPlusConfig.java b/mt-pay/src/main/java/com/mtkj/mtpay/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..65aa321 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/config/MyBatisPlusConfig.java @@ -0,0 +1,32 @@ +package com.mtkj.mtpay.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * MyBatis-Plus配置类 + */ +@Slf4j +@Configuration +@MapperScan("com.mtkj.mtpay.mapper") +public class MyBatisPlusConfig { + + /** + * 分页插件配置 + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + log.info("初始化MyBatis-Plus分页插件,数据库类型: {}", DbType.MYSQL); + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 添加分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + log.info("MyBatis-Plus分页插件配置完成"); + return interceptor; + } +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/config/MyMetaObjectHandler.java b/mt-pay/src/main/java/com/mtkj/mtpay/config/MyMetaObjectHandler.java new file mode 100644 index 0000000..e705d37 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/config/MyMetaObjectHandler.java @@ -0,0 +1,31 @@ +package com.mtkj.mtpay.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * MyBatis-Plus自动填充处理器 + * 用于自动填充创建时间和更新时间 + */ +@Slf4j +@Component +public class MyMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + log.debug("开始插入填充..."); + this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); + this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); + } + + @Override + public void updateFill(MetaObject metaObject) { + log.debug("开始更新填充..."); + this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); + } +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProduct.java b/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProduct.java new file mode 100644 index 0000000..31d8b14 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProduct.java @@ -0,0 +1,64 @@ +package com.mtkj.mtpay.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品实体类 + */ +@TableName(value = "mt_product") +@Data +public class MtProduct { + + /** + * 商品ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 商品名称 + */ + @TableField(value = "name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String name; + + /** + * 商品价格(基础价格,SKU可能有不同价格) + */ + @TableField(value = "price", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL) + private BigDecimal price; + + /** + * 主图URL(最大4000字符) + */ + @TableField(value = "main_image", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String mainImage; + + /** + * 商品状态:ACTIVE-上架,INACTIVE-下架,DELETED-已删除 + */ + @TableField(value = "status", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String status; + + /** + * 店铺ID + */ + @TableField(value = "shop_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT) + private Long shopId; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProductSku.java b/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProductSku.java new file mode 100644 index 0000000..c647f65 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProductSku.java @@ -0,0 +1,100 @@ +package com.mtkj.mtpay.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品SKU实体类 + */ +@TableName(value = "mt_product_sku") +@Data +public class MtProductSku { + + /** + * SKU ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 商品ID + */ + @TableField(value = "product_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT) + private Long productId; + + /** + * SKU编码(最大2000字符) + */ + @TableField(value = "sku", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String sku; + + /** + * 价格 + */ + @TableField(value = "price", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL) + private BigDecimal price; + + /** + * 货币(ISO 4217三位币种代码,如USD、CNY) + */ + @TableField(value = "currency", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String currency; + + /** + * 库存数量 + */ + @TableField(value = "stock", jdbcType = org.apache.ibatis.type.JdbcType.INTEGER) + private Integer stock; + + /** + * 销售属性名称(LONGTEXT,JSON格式,如:[{"name":"颜色","value":"红色"},{"name":"尺寸","value":"大号"}]) + */ + @TableField(value = "sales_attrs", jdbcType = org.apache.ibatis.type.JdbcType.LONGVARCHAR) + private String salesAttrs; + + /** + * SKU图片URL(最大4000字符) + */ + @TableField(value = "sku_image", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String skuImage; + + /** + * 重量(单位:克) + */ + @TableField(value = "weight", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL) + private BigDecimal weight; + + /** + * 大小/尺寸(JSON格式,如:{"length":10,"width":5,"height":3},单位:厘米) + */ + @TableField(value = "size", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String size; + + /** + * 规格(文本描述,最大2000字符) + */ + @TableField(value = "specification", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String specification; + + /** + * SKU状态:ACTIVE-启用,INACTIVE-禁用 + */ + @TableField(value = "status", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR) + private String status; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductMapper.java b/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductMapper.java new file mode 100644 index 0000000..108c8e5 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductMapper.java @@ -0,0 +1,13 @@ +package com.mtkj.mtpay.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mtkj.mtpay.entity.MtProduct; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品Mapper接口 + */ +@Mapper +public interface MtProductMapper extends BaseMapper { +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductSkuMapper.java b/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductSkuMapper.java new file mode 100644 index 0000000..b24c92c --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/mapper/MtProductSkuMapper.java @@ -0,0 +1,13 @@ +package com.mtkj.mtpay.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mtkj.mtpay.entity.MtProductSku; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品SKU Mapper接口 + */ +@Mapper +public interface MtProductSkuMapper extends BaseMapper { +} +