修复资产负债表金额统计异常

This commit is contained in:
wuyan
2025-07-06 10:37:29 +08:00
parent 89ce78941e
commit 51d53775ae
8 changed files with 267 additions and 136 deletions

View File

@ -26,8 +26,11 @@ import com.jinbooks.util.DateUtils;
import lombok.*;
import org.apache.commons.lang3.StringUtils;
import java.io.Serial;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
@ -47,10 +50,11 @@ import java.util.List;
public class StatementParamsDto extends PageQuery {
/**
*
*/
private static final long serialVersionUID = -3371902023167307161L;
/**
*
*/
@Serial
private static final long serialVersionUID = -3371902023167307161L;
/**
* 账套ID
*/
private String bookId;
@ -123,13 +127,28 @@ public class StatementParamsDto extends PageQuery {
this.year = Integer.parseInt(reportDate.substring(0, 4));
this.month = null;
this.quarter = null;
// 设置全年起始和结束日期
this.dateRange = new String[]{this.year + "-01",this.year + "-12"};
//年初日期
this.dateRangeStart = year + "-01-01";
//年终日期
this.dateRangeEnd = year + "-12-31";
this.reportDate = this.year + "-12";
// 年初日期固定
this.dateRangeStart = this.year + "-01-01";
// 当前系统日期
LocalDate now = LocalDate.now();
int currentYear = now.getYear();
if (this.year == currentYear) {
// 当前是本年度,终止为本月最后一天
int currentMonth = now.getMonthValue();
LocalDate lastDayOfCurrentMonth = now.with(TemporalAdjusters.lastDayOfMonth());
// 设置 dateRange 为 01 到当前月
this.dateRange = new String[]{
String.format("%d-01", this.year),
String.format("%d-%02d", this.year, currentMonth)
};
this.dateRangeEnd = lastDayOfCurrentMonth.toString();
this.reportDate = String.format("%d-%02d", this.year, currentMonth);
} else {
// 非本年度,默认整年
this.dateRange = new String[]{this.year + "-01", this.year + "-12"};
this.dateRangeEnd = this.year + "-12-31";
this.reportDate = this.year + "-12";
}
} else if (StatementPeriodTypeEnum.MONTH.getValue().equals(this.periodType)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
var date = java.time.YearMonth.parse(reportDate, formatter);
@ -161,8 +180,8 @@ public class StatementParamsDto extends PageQuery {
this.month = null;
if (this.quarter == 1) {
//报告年月
this.reportDate = this.year + "-03";
//报告年月
this.reportDate = this.year + "-03";
//季初日期
this.dateRangeStart = this.year + "-01-01";
//季末日期
@ -170,8 +189,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-01", this.year + "-03"};
} else if (this.quarter == 2) {
//报告年月
this.reportDate = this.year + "-06";
//报告年月
this.reportDate = this.year + "-06";
//季初日期
this.dateRangeStart = this.year + "-04-01";
//季末日期
@ -179,8 +198,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-04", this.year + "-06"};
} else if (this.quarter == 3) {
//报告年月
this.reportDate = this.year + "-09";
//报告年月
this.reportDate = this.year + "-09";
//季初日期
this.dateRangeStart = this.year + "-07-01";
//季末日期
@ -188,8 +207,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-07", this.year + "-09"};
} else if (this.quarter == 4) {
//报告年月
this.reportDate = this.year + "-12";
//报告年月
this.reportDate = this.year + "-12";
//季初日期
this.dateRangeStart = this.year + "-10-01";
//季末日期
@ -200,17 +219,17 @@ public class StatementParamsDto extends PageQuery {
this.year = Integer.parseInt(reportDate.substring(0, 4));
this.half = parseHalfYear(reportDate.substring(5, 7));
if (this.half == 1) {
//报告年月
this.reportDate = this.year + "-06";
//起始-终结日期
//报告年月
this.reportDate = this.year + "-06";
//起始-终结日期
this.dateRangeStart = this.year + "-01-01";
this.dateRangeEnd = this.year + "-06-30";
//月份范围
this.dateRange = new String[]{this.year + "-01", this.year + "-06"};
} else if (this.half == 2) {
//报告年月
this.reportDate = this.year + "-12";
//起始-终结日期
//报告年月
this.reportDate = this.year + "-12";
//起始-终结日期
this.dateRangeStart = this.year + "-07-01";
this.dateRangeEnd = this.year + "-12-31";
//月份范围
@ -248,13 +267,20 @@ public class StatementParamsDto extends PageQuery {
* 获取时间范围中的所有月份
*/
public List<String> getAllMonths() {
return getAllMonths(null);
}
public List<String> getAllMonths(String currentMonth) {
List<String> months = new ArrayList<>();
if (dateRange == null || dateRange.length != 2) {
throw new IllegalArgumentException("dateRange must contain exactly two elements: start and end.");
}
YearMonth start = YearMonth.parse(dateRange[0]);
YearMonth end = YearMonth.parse(dateRange[1]);
YearMonth end = currentMonth == null ? YearMonth.parse(dateRange[1])
: currentMonth.compareTo(dateRange[1]) > 0
? YearMonth.parse(dateRange[1])
: YearMonth.parse(currentMonth);
if (start.isAfter(end)) {
throw new IllegalArgumentException("Start date must be before or equal to end date.");
@ -269,6 +295,7 @@ public class StatementParamsDto extends PageQuery {
return months;
}
/**
* 判断是否是季报所在月份
*
@ -281,6 +308,7 @@ public class StatementParamsDto extends PageQuery {
/**
* 判断是否季末
*
* @param yyyy_MM 2025-03 2025-06 2025-09 2025-12
* @return boolean
*/
@ -303,6 +331,7 @@ public class StatementParamsDto extends PageQuery {
/**
* 判断是否12月
*
* @param yyyy_MM 2025-12
* @return boolean
*/

View File

@ -19,11 +19,18 @@
package com.jinbooks.persistence.mapper;
import com.jinbooks.entity.statement.StatementSubjectBalance;
import com.jinbooks.entity.statement.dto.StatementParamsDto;
import com.jinbooks.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface StatementSubjectBalanceMapper extends BaseMapperPlus<StatementSubjectBalanceMapper, StatementSubjectBalance, StatementSubjectBalance> {
List<StatementSubjectBalance> groupCodeSubjectBalance(@Param("dto") StatementParamsDto dto,
@Param("allMonths") List<String> allMonths,
@Param("minPeriod") String minPeriod,
@Param("maxPeriod") String maxPeriod);
}

View File

@ -60,7 +60,7 @@ public interface StatementBalanceSheetService {
void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules);
void refreshItemsBalance(List<StatementBalanceSheetItem> items,
String bookId, String yearPeriod);
String bookId, String yearPeriod, int updateParams);
StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items);

View File

@ -105,7 +105,7 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
lqw.eq(StatementBalanceSheetItem::getBookId, bookId);
lqw.eq(StatementBalanceSheetItem::getBalanceSheetId, ConstsSysConfig.SYS_CONFIG_TEMPLATE_ID);
List<StatementBalanceSheetItem> balanceSheets = statementBalanceSheetItemMapper.selectList(lqw);
statementBalanceSheetService.refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId));
statementBalanceSheetService.refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId), 3);
StatementBalanceSheetItemListVo itemListVo = statementBalanceSheetService.insertSubtotals(balanceSheets);
itemListVo.getAssets().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
itemListVo.getLiability().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));

View File

@ -91,7 +91,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
StatementBalanceSheet balanceSheet = balanceSheetMapper.selectOne(lqw);
String currentTerm = configSysService.getCurrentTerm(dto.getBookId());
List<String> allMonths = dto.getAllMonths();
List<String> allMonths = dto.getAllMonths(currentTerm);
List<StatementBalanceSheetItem> items;
// 查询范围包含了当前期,或者没数据,则实时统计
boolean isNull = balanceSheet == null;
@ -126,12 +126,15 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
//balanceSheetMapper.insert(balanceSheet);
}
// 遍历月份,统计总金额
for (String month : allMonths) {
refreshItemsBalance(items, dto.getBookId(), month);
// 统计总金额,因为是期末和年初,则只需要统计第一个月和最后一个月的数
if (allMonths.size() == 1) {
refreshItemsBalance(items, dto.getBookId(), allMonths.get(0), 3);
} else {
refreshItemsBalance(items, dto.getBookId(), allMonths.get(0), 1);
refreshItemsBalance(items, dto.getBookId(), allMonths.get(allMonths.size() - 1), 2);
}
}
}else {// 拉取历史数据
} else {// 拉取历史数据
// 查询条目
LambdaQueryWrapper<StatementBalanceSheetItem> itemLqw = Wrappers.lambdaQuery();
itemLqw.eq(StatementBalanceSheetItem::getBookId, dto.getBookId());
@ -367,13 +370,14 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
/**
* 刷新信息项对应的余额数据
*
* @param items 信息项组
* @param bookId 所属账簿
* @param yearPeriod 账期
* @param items 信息项组
* @param bookId 所属账簿
* @param yearPeriod 账期
* @param updateParams 需要更新的金额项1年初2期末3同时
*/
@Override
public void refreshItemsBalance(List<StatementBalanceSheetItem> items,
String bookId, String yearPeriod) {
String bookId, String yearPeriod, int updateParams) {
// 方便更新参数
Map<String, StatementBalanceSheetItem> mapSheet = items.stream()
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item));
@ -383,7 +387,9 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
lqwRule.in(StatementRules::getItemCode, itemCodes);
lqwRule.eq(StatementRules::getBookId, bookId);
lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name());
// 相关的所有规则
List<StatementRules> rules = rulesMapper.selectList(lqwRule);
// 所有规则下的绑定科目编号
List<String> subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList();
if (CollectionUtils.isNotEmpty(subjectCodes)) {
// 查询科目余额
@ -400,11 +406,19 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
updateRuleBalance(subjectBalance, statementRules);
StatementBalanceSheetItem balanceSheet = mapSheet.get(statementRules.getItemCode());
if (StatementSymbolEnum.PLUS.getValue().equals(statementRules.getSymbol())) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
if (updateParams == 1 || updateParams == 3) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
}
if (updateParams == 2 || updateParams == 3) {
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
}
} else {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
if (updateParams == 1 || updateParams == 3) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
}
if (updateParams == 2 || updateParams == 3) {
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
}
}
}
}
@ -545,7 +559,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
initialSum = initialSum.add(
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
);
} else if (StatementSymbolEnum.MINUS.getValue().equals(child.getSymbol())){
} else if (StatementSymbolEnum.MINUS.getValue().equals(child.getSymbol())) {
currentSum = currentSum.subtract(
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
);
@ -562,14 +576,21 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
@Override
public void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules) {
if (subjectBalance != null) {
statementRules.setOpeningYearBalance(subjectBalance.getOpeningYearBalanceDebit()
.subtract(subjectBalance.getOpeningYearBalanceCredit()));
statementRules.setClosingBalance(subjectBalance.getBalance());
} else {
if (statementRules != null && statementRules.getOpeningYearBalance() == null) {
statementRules.setOpeningYearBalance(BigDecimal.ZERO);
}
if (statementRules != null && statementRules.getClosingBalance() == null) {
statementRules.setClosingBalance(BigDecimal.ZERO);
}
if (subjectBalance != null && statementRules != null) {
statementRules.setOpeningYearBalance(
statementRules.getOpeningYearBalance().add(
subjectBalance.getOpeningYearBalanceDebit()
.subtract(subjectBalance.getOpeningYearBalanceCredit()))
);
statementRules.setClosingBalance(statementRules.getClosingBalance().add(subjectBalance.getBalance()));
}
}
}

View File

@ -360,52 +360,59 @@ public class StatementReportServiceImpl implements StatementReportService {
@Override
public Message<List<StatementSubjectBalance>> subjectBalance(StatementParamsDto dto) {
dto.parse();
List<String> allMonths = dto.getAllMonths();
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
lqw.in(StatementSubjectBalance::getYearPeriod, allMonths);
lqw.eq(StatementSubjectBalance::getBookId, dto.getBookId());
lqw.eq(!dto.getShowAll(), StatementSubjectBalance::getIsVoucher, YesNoEnum.y.name());
List<StatementSubjectBalance> res = subjectBalanceMapper.selectList(lqw);
String currentTerm = configSysService.selectConfigByKey(dto.getBookId(), ConstsSysConfig.SYS_PAYMENT_TERM_CURRENT);
List<String> allMonths = dto.getAllMonths(currentTerm);
// 拉取父级数据
List<String> subjectIds = new ArrayList<>(res.stream().map(StatementSubjectBalance::getSourceId).toList());
List<String> parentIds = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.y.name()))
.map(StatementSubjectBalance::getParentId).toList();
subjectIds.addAll(parentIds);
if (!subjectIds.isEmpty()) {
LambdaQueryWrapper<BookSubject> lqwSubject = Wrappers.lambdaQuery();
lqwSubject.eq(BookSubject::getBookId, dto.getBookId());
List<BookSubject> bookSubjects = bookSubjectMapper.selectList(lqwSubject);
// 找出所有父级
List<String> subjectPaths = new ArrayList<>();
bookSubjects.forEach(bookSubject -> {
for (String subjectId : subjectIds) {
if (bookSubject.getIdPath().contains(subjectId)) {
subjectPaths.addAll(List.of(bookSubject.getIdPath().split("/")));
}
}
});
// 创建父级
List<StatementSubjectBalance> balanceList = bookSubjects.stream()
.filter(bookSubject -> subjectPaths.contains(bookSubject.getId()))
.map(subject -> subjectBalanceService.create(subject, dto.getReportDate()))
.toList();
// 合并
Set<String> existingSourceIds = res.stream().map(StatementSubjectBalance::getSourceId).collect(Collectors.toSet());
for (StatementSubjectBalance item : balanceList) {
if (!existingSourceIds.contains(item.getSourceId())) {
res.add(item);
}
}
List<StatementSubjectBalance> res = null;
if (allMonths.size() > 1) {
res = subjectBalanceMapper.groupCodeSubjectBalance(dto, allMonths,allMonths.get(0), allMonths.get(allMonths.size() - 1));
} else {
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
lqw.in(StatementSubjectBalance::getYearPeriod, allMonths);
lqw.eq(StatementSubjectBalance::getBookId, dto.getBookId());
lqw.eq(!dto.getShowAll(), StatementSubjectBalance::getIsVoucher, YesNoEnum.y.name());
res = subjectBalanceMapper.selectList(lqw);
}
// // 拉取父级数据
// List<String> subjectIds = new ArrayList<>(res.stream().map(StatementSubjectBalance::getSourceId).toList());
// List<String> parentIds = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.y.name()))
// .map(StatementSubjectBalance::getParentId).toList();
// subjectIds.addAll(parentIds);
// if (!subjectIds.isEmpty()) {
// LambdaQueryWrapper<BookSubject> lqwSubject = Wrappers.lambdaQuery();
// lqwSubject.eq(BookSubject::getBookId, dto.getBookId());
// List<BookSubject> bookSubjects = bookSubjectMapper.selectList(lqwSubject);
// // 找出所有父级
// Set<String> subjectPaths = new HashSet<>();
// bookSubjects.forEach(bookSubject -> {
// for (String subjectId : subjectIds) {
// if (bookSubject.getIdPath().contains(subjectId)) {
// subjectPaths.addAll(List.of(bookSubject.getIdPath().split("/")));
// }
// }
// });
// // 创建父级
// List<StatementSubjectBalance> balanceList = bookSubjects.stream()
// .filter(bookSubject -> subjectPaths.contains(bookSubject.getId()))
// .map(subject -> subjectBalanceService.create(subject, dto.getReportDate()))
// .toList();
// // 合并
// Set<String> existingSourceIds = res.stream().map(StatementSubjectBalance::getSourceId).collect(Collectors.toSet());
// for (StatementSubjectBalance item : balanceList) {
// if (!existingSourceIds.contains(item.getSourceId())) {
// res.add(item);
// }
// }
// }
// counterBalance(res);
// 按照科目编号升序排列
res.sort(Comparator.comparing(StatementSubjectBalance::getSubjectCode));
if (!dto.getShowAux()) {
res = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.n.name())).toList();
}
// if (!dto.getShowAux()) {
// res = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.n.name())).toList();
// }
return new Message<>(res);
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jinbooks.persistence.mapper.StatementSubjectBalanceMapper">
<select id="groupCodeSubjectBalance" resultType="com.jinbooks.entity.statement.StatementSubjectBalance">
SELECT
sb.subject_code,
sb.subject_name,
sb.source_id,
sb.parent_id,
sb.is_auxiliary,
-- 年初余额只取1月
SUM(CASE WHEN sb.year_period = #{minPeriod} THEN sb.opening_balance_debit ELSE 0 END) AS
opening_balance_debit,
SUM(CASE WHEN sb.year_period = #{minPeriod} THEN sb.opening_balance_credit ELSE 0 END) AS
opening_balance_credit,
-- 本期发生额
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.current_period_debit ELSE 0 END) AS current_period_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.current_period_credit ELSE 0 END) AS current_period_credit,
-- 本年累计发生额取最后一个月的累计值需外部传入最终月份如2025-08
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.year_to_date_debit ELSE 0 END) AS year_to_date_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.year_to_date_credit ELSE 0 END) AS year_to_date_credit,
-- 期末余额(取最后一个月)
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.closing_balance_debit ELSE 0 END) AS
closing_balance_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.closing_balance_credit ELSE 0 END) AS
closing_balance_credit
FROM jbx_statement_subject_balance sb
WHERE sb.deleted = 'n'
AND sb.book_id = #{dto.bookId}
<if test="dto.showAll == false">
AND sb.is_voucher = 'y'
</if>
<if test="allMonths != null and allMonths.size() > 0">
AND sb.year_period IN
<foreach collection="allMonths" item="month" open="(" separator="," close=")">
#{month}
</foreach>
</if>
GROUP BY
sb.subject_code,
sb.subject_name,
sb.source_id,
sb.parent_id,
sb.is_auxiliary
ORDER BY sb.subject_code ASC
</select>
</mapper>

View File

@ -1,16 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="300">
<Configuration status="WARN" monitorInterval="300">
<Appenders>
<Console name="consolePrint" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss.SSS} %highlight{%level} [%t] %logger{36}:%L - %msg%n"/>
<!-- 控制台输出 -->
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} [%t] %style{%logger{36}}{cyan}:%L - %msg%n"
disableAnsi="false" noConsoleNoAnsi="false"/>
</Console>
<!-- 输出到文件按天或者超过128MB分割 -->
<RollingFile name="RollingFile" fileName="logs/jinbooks.log"
<!-- 滚动日志输出:每天生成 + 超过128MB滚动最多保留15个文件 -->
<RollingFile name="RollingFileAppender"
fileName="logs/jinbooks.log"
filePattern="logs/$${date:yyyyMMdd}/jinbooks-%d{yyyy-MM-dd}-%i.log.gz">
<!-- 需要记录的级别 -->
<!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> -->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5level [%t] (%logger{36}:%L) - %msg%n"/>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] (%logger{36}:%L) - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy/>
<TimeBasedTriggeringPolicy/>
@ -21,40 +24,50 @@
</Appenders>
<Loggers>
<!-- 设置 MyBatis 和 MyBatis-Plus 的日志级别 -->
<!-- MyBatis 相关调试日志 -->
<Logger name="com.baomidou.mybatisplus" level="DEBUG" additivity="false">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis" level="DEBUG" additivity="false">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
</Logger>
<!-- 更详细的 SQL 执行日志 -->
<Logger name="org.apache.ibatis.executor.statement" level="TRACE" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis.transaction.jdbc" level="TRACE" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<!-- SQL 执行器详细日志 -->
<Logger name="org.apache.ibatis.executor.statement" level="INFO" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis.transaction.jdbc" level="INFO" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger level="TRACE" name="com.jinbooks.persistence.mapper" ></Logger>
<Logger level="OFF" name="org.hibernate.validator.internal.util.Version"></Logger>
<!-- 项目 DAO 层日志 -->
<Logger name="com.jinbooks.persistence.mapper" level="TRACE" additivity="false">
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger level="INFO" name="org.apache.logging"></Logger>
<Logger level="INFO" name="org.springframework"></Logger>
<Logger level="DEBUG" name="com.jinbooks"></Logger>
<Logger level="ERROR" name="com.alibaba.nacos"></Logger>
<Logger level="ERROR" name="org.reflections.Reflections"></Logger>
<Logger level="ERROR" name="RocketmqRemoting"></Logger>
<Logger level="OFF" name="org.quartz"></Logger>
<!-- 关闭不需要的日志输出 -->
<Logger name="org.hibernate.validator.internal.util.Version" level="OFF"/>
<Logger name="org.quartz" level="OFF"/>
<!-- 常见框架日志配置 -->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.apache.logging" level="INFO"/>
<Logger name="com.alibaba.nacos" level="ERROR"/>
<Logger name="org.reflections.Reflections" level="ERROR"/>
<Logger name="RocketmqRemoting" level="ERROR"/>
<!-- 项目主包日志 -->
<Logger name="com.jinbooks" level="DEBUG"/>
<!-- 根日志配置 -->
<Root level="INFO">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Root>
</Loggers>
</Configuration>